Obsessed { since } rank; Fieri on the landing page

504ebaf · Gabriel Morell · 2026-10-28 20:18

33 files +276 -61
Message
{commit_body(@commit)}

Files changed

modified README.md
+5 −3
@@ -2,8 +2,8 @@
2 2
3 3 Where are we going for lunch? Not there again.
4 4
5 −People pin restaurants on an OpenStreetMap map and rank each one **Always**,
6 −**Positive**, **Neutral** or **Never**. When a group goes out, the app suggests
5 +People pin restaurants on an OpenStreetMap map and rank each one **Obsessed**
6 +(since a date), **Always**, **Positive**, **Neutral** or **Never**. When a group goes out, the app suggests
7 7 somewhere from what everyone going likes and where the team hasn't been
8 8 lately, and the group logs where it actually went so the next pick knows.
9 9
@@ -94,7 +94,9 @@ may also need `proxy-read-timeout` raised past the 15 s keep-alive.
94 94 All in `src/suggest.rs`, pure functions with unit tests. For the people going:
95 95
96 96 - **Veto.** If anyone going ranked a place *Never*, it's out.
97 −- **Liked.** The group's average weight: Always 4, Positive 2, Neutral 1.
97 +- **Liked.** The group's average weight: Obsessed 6, Always 4, Positive 2,
98 + Neutral 1. Obsessed records when it started; picking it again keeps that
99 + date, and it can be backdated from the rank widget.
98 100 Unranked counts as Neutral, so nobody has to rank everything.
99 101 - **Freshness.** `1 / (1 + 3 × load)`, where load sums every visit in the last
100 102 70 days, each decayed by a 10-day half-life. Yesterday's spot keeps about a
modified ?
+0 −0

Binary file — not rendered.

modified assets/f/js/map.js
+2 −2
@@ -22,9 +22,9 @@ const TILE_THEMES = {
22 22 sky: "blueprint", forest: "night", clays: "night",
23 23 };
24 24
25 −// Rank colours, as in the badges: success / lime / neutral / error.
25 +// Rank colours, as in the badges: flame / success / lime / neutral / error.
26 26 const RANK_COLORS = {
27 − always: "#16a34a", positive: "#84cc16", neutral: "#a8a29e", never: "#dc2626",
27 + obsessed: "#ea580c", always: "#16a34a", positive: "#84cc16", neutral: "#a8a29e", never: "#dc2626",
28 28 };
29 29 const UNRANKED = "#3b82f6";
30 30 const CANDIDATE = "#f59e0b";
modified migration/src/lib.rs
+2 −0
@@ -3,6 +3,7 @@ pub use sea_orm_migration::prelude::*;
3 3 mod m20240101_000001_create_auth_tables;
4 4 mod m20261028_000001_create_lunch_tables;
5 5 mod m20261028_000002_create_outings;
6 +mod m20261028_000003_obsessed;
6 7
7 8 pub struct Migrator;
8 9
@@ -13,6 +14,7 @@ impl MigratorTrait for Migrator {
13 14 Box::new(m20240101_000001_create_auth_tables::Migration),
14 15 Box::new(m20261028_000001_create_lunch_tables::Migration),
15 16 Box::new(m20261028_000002_create_outings::Migration),
17 + Box::new(m20261028_000003_obsessed::Migration),
16 18 ]
17 19 }
18 20 }
added migration/src/m20261028_000003_obsessed.rs
+46 −0
@@ -0,0 +1,46 @@
1 +//! `Obsessed { since }`: a rank stronger than Always, carrying the date the
2 +//! obsession began. The rank column already holds the kind as a string
3 +//! ("obsessed" fits its 16 chars); the date gets its own column, set only
4 +//! when the rank is "obsessed".
5 +use sea_orm_migration::prelude::*;
6 +
7 +#[derive(DeriveMigrationName)]
8 +pub struct Migration;
9 +
10 +#[async_trait::async_trait]
11 +impl MigrationTrait for Migration {
12 + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
13 + manager
14 + .alter_table(
15 + Table::alter()
16 + .table(Rankings::Table)
17 + .add_column(ColumnDef::new(Rankings::ObsessedSince).date().null())
18 + .to_owned(),
19 + )
20 + .await
21 + }
22 +
23 + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
24 + // An obsession without its date isn't representable; fall back to
25 + // the next strongest rank.
26 + manager
27 + .exec_stmt(
28 + Query::update()
29 + .table(Rankings::Table)
30 + .value(Rankings::Rank, "always")
31 + .and_where(Expr::col(Rankings::Rank).eq("obsessed"))
32 + .to_owned(),
33 + )
34 + .await?;
35 + manager
36 + .alter_table(Table::alter().table(Rankings::Table).drop_column(Rankings::ObsessedSince).to_owned())
37 + .await
38 + }
39 +}
40 +
41 +#[derive(DeriveIden)]
42 +enum Rankings {
43 + Table,
44 + Rank,
45 + ObsessedSince,
46 +}
modified src/entities/rankings.rs
+78 −10

Click to load diff…

modified src/handlers/areas.rs
+3 −1

Click to load diff…

modified src/handlers/lunch.rs
+1 −1

Click to load diff…

modified src/handlers/outings.rs
+2 −2

Click to load diff…

modified src/handlers/restaurants.rs
+59 −13

Click to load diff…

modified src/lib.rs
+1 −1

Click to load diff…

modified src/suggest.rs
+25 −3

Click to load diff…

modified templates/_macros.html
+6 −5

Click to load diff…

modified templates/areas/show.html
+1 −1

Click to load diff…

modified templates/index.html
+4 −1

Click to load diff…

modified templates/lunch/_plan.html
+1 −1

Click to load diff…

modified templates/restaurants/_rank.html
+24 −15

Click to load diff…

modified templates/restaurants/show.html
+1 −1

Click to load diff…

modified tests/templates.rs
+15 −1

Click to load diff…

Parents: 7def6a5