97 lines
4.4 KiB
Markdown
97 lines
4.4 KiB
Markdown
# TODO
|
|
|
|
Ordered roughly by importance. Items near the top either caused real
|
|
failures already or block going live.
|
|
|
|
## 1. Deletions never propagate — weekly full resync and prune
|
|
|
|
`_since` returns records ST considers *updated*. A deleted user is not
|
|
returned at all, so their row stays in `people` forever. This has already
|
|
caused two failed runs: once with a deleted rep chosen as `reps[0]` (45
|
|
identical 404s), once with a deleted member failing mid-run.
|
|
|
|
started := time.Now().Unix()
|
|
users, _ := client.ListUsers(ctx, 0) // full pull, ~176 requests
|
|
store.UpsertPeople(users, eligible)
|
|
store.PruneStale(started) // DELETE FROM people WHERE synced_at < ?
|
|
store.SetLastSync(started)
|
|
|
|
Guards:
|
|
|
|
- Only prune after a `since=0` pass. A delta pass refreshes a handful of
|
|
rows and would delete everything else.
|
|
- Refuse to prune if it would remove more than a few percent of the table.
|
|
A bug that silently empties the cache takes out every reconcile until
|
|
someone notices.
|
|
|
|
## 3. Small fixes, one commit
|
|
|
|
- **`failed` in the reconcile summary.** Run 10 logged
|
|
`0 assigned, 0 skipped` after 45 failures. A wholly failed run is
|
|
currently indistinguishable from an empty one.
|
|
- **Verify the agent before the loop.** One `GetUser(agent)` at the top
|
|
of `reconcile`; abort with a clear message rather than failing once per
|
|
member.
|
|
- **Prune a member's cache row on a 404 from `AssignAgent`.** Reactive
|
|
and self-healing: a stale row fails once instead of on every future run
|
|
of that department.
|
|
- **Live `IsRep` check in the handler.** Chapter and department come from
|
|
a live `GetUser`, but nothing checks whether the person is still a rep.
|
|
Someone whose flag was removed can still trigger a full reconcile.
|
|
- **Add `sqlite` to the Dockerfile runtime stage.** Inspecting `skips`,
|
|
`runs`, or `sync_state` currently means a rebuild or a throwaway
|
|
container mounted on the volume.
|
|
|
|
## 4. Before going live
|
|
|
|
- **`VACUUM INTO` on a timer.** Volume snapshots of a live WAL database
|
|
are not safe to restore. The skip log is the only thing here that
|
|
cannot be regenerated.
|
|
- **Turn off `DRY_RUN`, redeploy.**
|
|
- **Backfill.** The webhook only fires when a rep is *newly* assigned the
|
|
role, so the existing 119 never trigger it. Run with `DRY_RUN` set
|
|
first and count the assignments in the log; expect roughly 2,300.
|
|
|
|
sqlite3 worker.db "SELECT id FROM people WHERE is_rep = 1;" | while read id; do
|
|
curl -s -o /dev/null -X POST "https://HOST/webhook?id=$id&s=$SECRET"
|
|
sleep 1
|
|
done
|
|
|
|
## 5. Deferred design decisions
|
|
|
|
- **Nightly sweep.** Without it, a rep who steps down keeps their
|
|
assignments and their replacement inherits nobody. Members added after
|
|
their department's rep signed up also stay unassigned until something
|
|
triggers that department again. Rep replacement was described as
|
|
frequent, so this matters more than the member-churn case.
|
|
- **Raise the fill-only consequence upstream.** The rule came from
|
|
outside the project. The concrete cost is now measurable: 14 reps at
|
|
three campuses will open the app to an empty list.
|
|
- **Schema migrations.** `CREATE TABLE IF NOT EXISTS` does not add
|
|
columns to an existing table. Changing the schema currently means
|
|
deleting the database and re-syncing, which will not be an option in
|
|
production.
|
|
- **License.** AGPLv3 if the goal is that other associations running a
|
|
modified copy must share changes; Apache-2.0 if the goal is that they
|
|
actually adopt it. Check first whether this is yours to license given
|
|
it is faculty association work.
|
|
|
|
## 6. Open questions for ST support
|
|
|
|
- Do a deleted or demoted rep's agent assignments stay active? This
|
|
decides whether departing reps permanently strand their members under
|
|
fill-only. Untested: the assignments observed as inactive were
|
|
deactivated by hand.
|
|
- `DELETE /agent_assignments/{id}` returns 404 on a row that
|
|
`GET /agent_assignments/{id}` returns fine. Either the path takes
|
|
something else or the handler is broken.
|
|
|
|
## 7. README corrections
|
|
|
|
- Work List rows are materialized by an ST job running on the half hour.
|
|
A new rep sees an empty list for up to 30 minutes after their
|
|
assignments are written. Confirmed: rows appeared exactly at :30. Worth
|
|
saying in whatever onboarding message reps get, or they will report it
|
|
as broken.
|
|
- Remove any claim that deleting a person deactivates their assignments.
|
|
That was done manually and the actual behaviour is unknown.
|