Skip to content

Commit 1a2aa52

Browse files
authored
Remove typeorm (#1814)
1 parent 2c7aec7 commit 1a2aa52

54 files changed

Lines changed: 1259 additions & 800 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/api.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,72 @@ jobs:
109109
run: cd api && make build
110110
- name: Run tests
111111
run: cd api && make api-test
112+
113+
# Ephemeral Postgres: alembic upgrade → Node schema contract + worker smoke → API tests
114+
# (alerts CRUD, /stats fixture, admin list routes, alembic_version).
115+
alerts_db_alembic_and_alerting:
116+
runs-on: ubuntu-latest
117+
services:
118+
postgres:
119+
image: postgres:16-alpine
120+
env:
121+
POSTGRES_USER: postgres
122+
POSTGRES_PASSWORD: postgres
123+
POSTGRES_DB: postgres
124+
ports:
125+
- 5432:5432
126+
options: >-
127+
--health-cmd "pg_isready -U postgres"
128+
--health-interval 5s
129+
--health-timeout 5s
130+
--health-retries 10
131+
env:
132+
PRISM_ALERTS_DATABASE_URL: postgresql://postgres:postgres@localhost:5432/postgres
133+
# Required to import prism_app.main during pytest collection (see docker-compose.yml defaults).
134+
KOBO_USERNAME: kobo_user
135+
KOBO_PASSWORD: test
136+
steps:
137+
- uses: actions/checkout@v4
138+
- uses: actions/setup-python@v5
139+
with:
140+
python-version: "3.12"
141+
- uses: snok/install-poetry@v1
142+
with:
143+
version: 2.2.1
144+
virtualenvs-create: true
145+
virtualenvs-in-project: true
146+
- name: Install API dependencies
147+
run: |
148+
cd api
149+
poetry install
150+
- name: Upgrade pip (CVE-2026-1703)
151+
run: |
152+
cd api
153+
poetry run pip install --upgrade 'pip>=26.0'
154+
- name: Alembic upgrade head
155+
run: cd api && poetry run alembic upgrade head
156+
- uses: actions/setup-node@v4
157+
with:
158+
node-version: "20"
159+
- name: Alerting install and DB checks
160+
env:
161+
PUPPETEER_SKIP_DOWNLOAD: "true"
162+
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: "true"
163+
run: |
164+
cd alerting
165+
yarn install --frozen-lockfile
166+
yarn setup:common
167+
yarn check-alerts-db-contract
168+
yarn smoke-alerts-db-pool
169+
yarn smoke-alerting-workers
170+
- name: API alerts integration tests (same database)
171+
env:
172+
# Ubuntu runner Poetry venv has rasterio but not a full gdal_calc CLI like the API Docker image.
173+
SKIP_GDAL_MASK_STATS_TEST: "1"
174+
run: |
175+
cd api
176+
PYTHONPATH=. poetry run pytest \
177+
prism_app/tests/test_api.py \
178+
prism_app/tests/test_alerting.py \
179+
prism_app/tests/test_alerts_db_integration.py \
180+
-v --tb=short

alerting/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# Copy to `.env`. `src/db/pool.ts` loads it via dotenv for local `yarn` / `ts-node` (host port 54321).
12
PRISM_ALERTS_EMAIL_HOST=smtp.gmail.com
23
PRISM_ALERTS_EMAIL_USER=prism.alerts.wfp@gmail.com
34
PRISM_ALERTS_EMAIL_PASSWORD=test

alerting/.eslintrc

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,6 @@
7575
}
7676
]
7777
}
78-
},
79-
{
80-
"files": [
81-
"src/**/*.entity.{ts,js}"
82-
],
83-
"rules": {
84-
"import/no-cycle": "off"
85-
}
8678
}
8779
]
8880
}

alerting/README.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ There is a unique service running for all country specific frontends.
99

1010
## Database schema and migrations
1111

12-
The alerting stack uses the same PostgreSQL database as the PRISM API for `alert`, `user_info`, and `anticipatory_action_alerts`. **Python/Alembic under `api/alembic/` is the sole owner of new schema migrations** for this database. The TypeORM migration history in `migration/` remains useful as a record of how production was built, but **do not add new TypeORM migrations** for these tables or enums. Change SQLModel in `api/prism_app/database/`, add an Alembic revision under `api/alembic/versions/`, and run `alembic upgrade head` with `PRISM_ALERTS_DATABASE_URL` (see `api/README.md`).
12+
The alerting stack uses the same PostgreSQL database as the PRISM API for `alert`, `user_info`, and `anticipatory_action_alerts`. **Python/Alembic under `api/alembic/` is the sole owner of schema migrations** for this database. Change SQLModel in `api/prism_app/database/`, add an Alembic revision under `api/alembic/versions/`, and run `alembic upgrade head` with `PRISM_ALERTS_DATABASE_URL` (see `api/README.md`).
1313

1414
## Functionalities
1515

@@ -23,18 +23,20 @@ The alerting stack uses the same PostgreSQL database as the PRISM API for `alert
2323
- Alerts are triggered by a cron job running within the `alerting-node` process.
2424
- Run `docker compose up` to launch the `alerting-node` and `alerting-db` processes.
2525
- The system checks database entries to determine **which country** needs to be triggered.
26-
- Currently, **Mozambique is supported**. After the DB schema exists (Alembic baseline / TypeORM history in prod), seed local data from the **API** (same repo area that owns migrations)—see **Local dev seed data** in [`api/README.md`](../api/README.md): `poetry run python scripts/seed_alerts_db.py` from `api/`. Connection vars are `PRISM_ALERTS_DATABASE_URL` or `POSTGRES_*` in `api/.env`; for host access to `alerting-db`, use port `54321` as in [`.env.example`](./.env.example).
26+
- Currently, **Mozambique is supported**. After the DB schema exists, seed local data from the **API** (same repo area that owns migrations)—see **Local dev seed data** in [`api/README.md`](../api/README.md): `poetry run python scripts/seed_alerts_db.py` from `api/`. Connection vars are `PRISM_ALERTS_DATABASE_URL` or `POSTGRES_*` in `api/.env`; for host access to `alerting-db`, use port `54321` as in [`.env.example`](./.env.example).
2727

2828
- **country**: The target country for the alert.
2929
- **emails**: A list of email addresses that will receive the alert notification.
3030
- **prism_url**: The base URL of the PRISM platform for redirection link and screenshot capture.
3131
- **type**: Hazard type enum: `storm` | `flood` | `drought`.
3232

33-
The `type` column is a PostgreSQL ENUM (`anticipatory_action_alerts_type_enum`). It was originally created by TypeORM migration `1738850000000-add-type-to-anticipatory-action-alerts.ts`; the authoritative definition for new environments is the Alembic baseline under `api/alembic/versions/`.
33+
The `type` column is a PostgreSQL ENUM (`anticipatory_action_alerts_type_enum`) defined by the Alembic baseline under `api/alembic/versions/`.
3434

3535
### Optional: threshold `alert` rows + `user_info` (local testing)
3636

37-
The same API seed step loads a [Starlette Admin](https://github.com/jowilf/starlette-admin)–friendly `user_info` row and two sample `alert` rows (SQL under [`api/scripts/seed_local_alerts_dev.sql`](../api/scripts/seed_local_alerts_dev.sql)). **User password:** with `salt = 'false'`, the PRISM API validates this row using a **plain-text** password match ([`prism_app/auth.py`](../api/prism_app/auth.py))—use HTTP Basic `local_dev_user` / `localdev` when auth is enabled. Re-running the seed replaces the fixed `seed-alert-*@example.com` rows and leaves `user_info` unchanged if the username already exists.
37+
For [Starlette Admin](https://github.com/jowilf/starlette-admin) or API smoke tests, use the same seed step as above: from `api/`, run `poetry run python scripts/seed_alerts_db.py`. That executes [`api/scripts/seed_local_alerts_dev.sql`](../api/scripts/seed_local_alerts_dev.sql), which loads sample `alert` and `user_info` rows (and the Mozambique AA rows) in one shot. Re-running is safe: see comments at the top of that SQL file.
38+
39+
- **User password:** with `salt = 'false'`, the PRISM API validates this row using a **plain-text** password match ([`prism_app/auth.py`](../api/prism_app/auth.py))—use HTTP Basic `local_dev_user` / `localdev` when auth is enabled.
3840

3941
### Shared worker runner
4042

@@ -65,11 +67,35 @@ sudo docker compose run --entrypoint "yarn aa-flood-alert-worker --testEmail='em
6567
```
6668
- The provided emails replace the DB-configured recipients for test runs.
6769

70+
### Ethereal (fake SMTP, no credentials)
71+
72+
If **`PRISM_ALERTS_EMAIL_USER`** and **`PRISM_ALERTS_EMAIL_PASSWORD`** are both unset or empty, [`src/utils/email.ts`](./src/utils/email.ts) uses Nodemailer’s [Ethereal](https://ethereal.email) test inbox: it creates a disposable SMTP account, sends through `smtp.ethereal.email`, and logs a **preview URL** (`Preview URL: …`) you can open in a browser to read the message and attachments.
73+
74+
This is independent of **`--testEmail`**: you can keep using test addresses in the command; Ethereal still delivers to its fake SMTP and you inspect the result via the preview URL (those addresses are not a real inbox).
75+
76+
1. Ensure real SMTP env vars are not set (or remove them from `.env` / compose for local runs).
77+
2. Run a worker that sends mail (commands above, or threshold `alert-worker` if your DB triggers a send).
78+
3. Copy the logged preview link from the container or terminal output.
79+
80+
Each run may use a new Ethereal account. To reuse one inbox, configure Ethereal’s SMTP user/password yourself via `PRISM_ALERTS_EMAIL_USER`, `PRISM_ALERTS_EMAIL_PASSWORD`, and `PRISM_ALERTS_EMAIL_HOST` (e.g. `smtp.ethereal.email`).
81+
6882
### Flood data source
6983
- The flood worker reads `dates.json`: `https://data.earthobservation.vam.wfp.org/public-share/aa/flood/moz/dates.json`.
7084
- Email triggers when `trigger_status` is one of: `bankfull`, `moderate`, `severe`.
7185
- Email content follows the AA Flood design and includes a map screenshot and CTA link.
7286

87+
## CI and release checks (shared alerts database)
88+
89+
GitHub Actions job **`alerts_db_alembic_and_alerting`** (in [`.github/workflows/api.yml`](../.github/workflows/api.yml)) starts an ephemeral Postgres, runs `alembic upgrade head` from `api/`, then:
90+
91+
1. **`yarn check-alerts-db-contract`** — Validates tables/columns/types the Node workers query still match the migrated schema (`src/ci/check-alerts-db-contract.ts`). Requires `PRISM_ALERTS_DATABASE_URL`.
92+
2. **`yarn smoke-alerts-db-pool`** — Runs real `pg` queries used by threshold and AA workers (empty tables OK; `src/ci/smoke-alerts-db-pool.ts`).
93+
3. **`yarn smoke-alerting-workers`** — Runs `runAlertWorker()` plus AA storm/flood `SELECT`s on the same pool (`src/ci/smoke-alerting-workers.ts`; safe when there are no active alerts).
94+
95+
The same job then runs **`pytest`** on `test_api.py`, `test_alerting.py`, and **`test_alerts_db_integration.py`** so the API, `/stats` alerting fixture, admin list routes, and Alembic metadata align with that database. See [api/README.md](../api/README.md) (**Alerts database (CI integration + local)**).
96+
97+
**Before or right after the first production `alembic upgrade` on the shared alerts DB**, also smoke manually: full `alert-worker`, one AA worker **without** `--testEmail` (so the pool hits Postgres), and read-only Starlette Admin on `alert` / `user_info` / `anticipatory_action_alerts`.
98+
7399
## Server crons
74100
Alert workers are running as crons on the server. Edit with: `crontab -e`
75101
Crontab examples :

alerting/crons/cron_aa_flood_alert_run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cd ~/prism-app/alerting
44
# source secrets from AWS
55
source ../api/set_envs.sh
66

7-
docker compose run --rm --entrypoint 'yarn aa-flood-alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/aa_flood_alert_worker.log
7+
docker compose run --rm -e POSTGRES_SSL=true --entrypoint 'yarn aa-flood-alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/aa_flood_alert_worker.log
88

99
## To set up the cron job, run the following command on the server:
1010
# crontab -e

alerting/crons/cron_aa_storm_alert_run.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ cd ~/prism-app/alerting
44
# source secrets from AWS
55
source ../api/set_envs.sh
66

7-
docker compose run --rm --entrypoint 'yarn aa-storm-alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/aa_storm_alert_worker.log
7+
docker compose run --rm -e POSTGRES_SSL=true --entrypoint 'yarn aa-storm-alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/aa_storm_alert_worker.log
88

99
## To set up the cron job, run the following command on the server:
1010
# crontab -e
1111
## and then add the following line to the crontab file:
1212
## This will run the storm AA alerting script every hour at minute 0.
1313
# 0 * * * * ~/prism-app/alerting/crons/cron_aa_storm_alert_run.sh
14-
15-

alerting/crons/cron_alert_run.sh

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@ cd ~/prism-app/alerting
44
# source secrets from AWS
55
source ../api/set_envs.sh
66

7-
docker compose run --rm --entrypoint 'yarn alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/alert_worker.log
7+
docker compose run --rm -e POSTGRES_SSL=true --entrypoint 'yarn alert-worker' alerting-node 2>&1 | tee -a ~/prism-app/alerting/alert_worker.log
88

99
## To set up the cron job, run the following command on the server:
1010
# crontab -e
1111
## and then add the following line to the crontab file:
1212
# 0 1 * * * ~/prism-app/alerting/crons/cron_alert_run.sh
1313
## This will run the alerting script every day at 1:00 AM.
14-
15-

alerting/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ services:
2525
working_dir: /prism_app
2626
environment:
2727
- POSTGRES_HOST=alerting-db
28+
# Override host-oriented POSTGRES_PORT from alerting/.env (dotenv); DB listens on 5432 inside the network.
29+
- POSTGRES_PORT=5432
2830
- POSTGRES_USER=postgres
2931
- POSTGRES_DB=postgres
3032
- POSTGRES_PASSWORD=!ChangeMe!

alerting/migration/1616783964884-Initialize.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

alerting/migration/1621386893272-addActiveColumn.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)