mirror of
https://github.com/zaphar/kitchen.git
synced 2025-07-22 19:40:14 -04:00
Add api for getting a plan for a specific date
This commit is contained in:
parent
bba1d9ca19
commit
38582f66ab
@ -126,6 +126,36 @@
|
|||||||
},
|
},
|
||||||
"query": "insert into category_mappings\n (user_id, ingredient_name, category_name)\n values (?, ?, ?)\n on conflict (user_id, ingredient_name)\n do update set category_name=excluded.category_name\n"
|
"query": "insert into category_mappings\n (user_id, ingredient_name, category_name)\n values (?, ?, ?)\n on conflict (user_id, ingredient_name)\n do update set category_name=excluded.category_name\n"
|
||||||
},
|
},
|
||||||
|
"2e076acd2405d234daaa866e5a2ac1e10989fc8d2820f90aa722464a7b17db6b": {
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "plan_date: NaiveDate",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Date"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "recipe_id",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "count",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Int64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 2
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"query": "select plan_date as \"plan_date: NaiveDate\", recipe_id, count\n from plan_recipes\nwhere\n user_id = ?\n and plan_date = ?"
|
||||||
|
},
|
||||||
"37f382be1b53efd2f79a0d59ae6a8717f88a86908a7a4128d5ed7339147ca59d": {
|
"37f382be1b53efd2f79a0d59ae6a8717f88a86908a7a4128d5ed7339147ca59d": {
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
|
@ -208,6 +208,19 @@ async fn api_save_recipes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn api_plan_for_date(
|
||||||
|
Extension(app_store): Extension<Arc<storage::SqliteStore>>,
|
||||||
|
session: storage::UserIdFromSession,
|
||||||
|
Path(date): Path<chrono::NaiveDate>,
|
||||||
|
) -> api::PlanDataResponse {
|
||||||
|
use storage::{UserId, UserIdFromSession::FoundUserId};
|
||||||
|
if let FoundUserId(UserId(id)) = session {
|
||||||
|
app_store.fetch_meal_plan_for_date(&id, date).await.into()
|
||||||
|
} else {
|
||||||
|
api::Response::Unauthorized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn api_plan(
|
async fn api_plan(
|
||||||
Extension(app_store): Extension<Arc<storage::SqliteStore>>,
|
Extension(app_store): Extension<Arc<storage::SqliteStore>>,
|
||||||
session: storage::UserIdFromSession,
|
session: storage::UserIdFromSession,
|
||||||
@ -422,6 +435,7 @@ fn mk_v2_routes() -> Router {
|
|||||||
// mealplan api path routes
|
// mealplan api path routes
|
||||||
.route("/plan", get(api_plan).post(api_save_plan))
|
.route("/plan", get(api_plan).post(api_save_plan))
|
||||||
.route("/plan/since/:date", get(api_plan_since))
|
.route("/plan/since/:date", get(api_plan_since))
|
||||||
|
.route("/plan/at/:date", get(api_plan_for_date))
|
||||||
.route("/plan/all", get(api_all_plans))
|
.route("/plan/all", get(api_all_plans))
|
||||||
.route(
|
.route(
|
||||||
"/inventory",
|
"/inventory",
|
||||||
|
5
kitchen/src/web/storage/fetch_plan_for_date.sql
Normal file
5
kitchen/src/web/storage/fetch_plan_for_date.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
select plan_date as "plan_date: NaiveDate", recipe_id, count
|
||||||
|
from plan_recipes
|
||||||
|
where
|
||||||
|
user_id = ?
|
||||||
|
and plan_date = ?
|
@ -121,6 +121,12 @@ pub trait APIStore {
|
|||||||
user_id: S,
|
user_id: S,
|
||||||
) -> Result<Option<Vec<(String, i32)>>>;
|
) -> Result<Option<Vec<(String, i32)>>>;
|
||||||
|
|
||||||
|
async fn fetch_meal_plan_for_date<S: AsRef<str> + Send>(
|
||||||
|
&self,
|
||||||
|
user_id: S,
|
||||||
|
date: NaiveDate,
|
||||||
|
) -> Result<Option<Vec<(String, i32)>>>;
|
||||||
|
|
||||||
async fn fetch_meal_plans_since<S: AsRef<str> + Send>(
|
async fn fetch_meal_plans_since<S: AsRef<str> + Send>(
|
||||||
&self,
|
&self,
|
||||||
user_id: S,
|
user_id: S,
|
||||||
@ -583,6 +589,40 @@ impl APIStore for SqliteStore {
|
|||||||
Ok(Some(result))
|
Ok(Some(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_meal_plan_for_date<S: AsRef<str> + Send>(
|
||||||
|
&self,
|
||||||
|
user_id: S,
|
||||||
|
date: NaiveDate,
|
||||||
|
) -> Result<Option<Vec<(String, i32)>>> {
|
||||||
|
let user_id = user_id.as_ref();
|
||||||
|
struct Row {
|
||||||
|
pub plan_date: NaiveDate,
|
||||||
|
pub recipe_id: String,
|
||||||
|
pub count: i64,
|
||||||
|
}
|
||||||
|
// NOTE(jwall): It feels like I shouldn't have to use an override here
|
||||||
|
// but I do because of the way sqlite does types and how that interacts
|
||||||
|
// with sqlx's type inference machinery.
|
||||||
|
let rows = sqlx::query_file_as!(
|
||||||
|
Row,
|
||||||
|
"src/web/storage/fetch_plan_for_date.sql",
|
||||||
|
user_id,
|
||||||
|
date
|
||||||
|
)
|
||||||
|
.fetch_all(self.pool.as_ref())
|
||||||
|
.await?;
|
||||||
|
if rows.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for row in rows {
|
||||||
|
let (_, recipe_id, count): (NaiveDate, String, i64) =
|
||||||
|
(row.plan_date, row.recipe_id, row.count);
|
||||||
|
result.push((recipe_id, count as i32));
|
||||||
|
}
|
||||||
|
Ok(Some(result))
|
||||||
|
}
|
||||||
|
|
||||||
async fn fetch_latest_meal_plan<S: AsRef<str> + Send>(
|
async fn fetch_latest_meal_plan<S: AsRef<str> + Send>(
|
||||||
&self,
|
&self,
|
||||||
user_id: S,
|
user_id: S,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user