Skip to content

Commit

Permalink
menu api
Browse files Browse the repository at this point in the history
  • Loading branch information
33tm committed Feb 3, 2025
1 parent a6503ee commit 0eb16c2
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
33 changes: 33 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,39 @@ requested day's schedule, and a boolean indicating whether that schedule is an a
{"error": "Error parsing date string: the input \"aaa\" can't be parsed as ISO 8601."}
```

### GET /menu
Returns an object of [`Entries`](https://github.com/GunnWATT/watt/blob/main/docs/types.md#entry) corresponding to the
requested day's brunch and lunch menu.

##### Response schema
```ts
{brunch: {[item: string]: Entry}, lunch: {[item: string]: Entry}}
```
- `brunch` + `lunch`: The day's menu items as [`Entries`](https://github.com/GunnWATT/watt/blob/main/docs/types.md#entry).

##### Request parameters

| Parameter | Type | Description |
|---------------------|----------|-------------------------------------------------------------------------------------------------------------------------|
| `date` *(optional)* | `string` | An ISO timestamp representing the day to return the schedule for. If no date is provided, the current day will be used. |

##### HTTP status codes

| Status code | Description |
|-------------|-----------------------------------------------------------------------------|
| 200 | OK |
| 400 | `query.date` was provided but not a string, or invalid as an ISO timestamp. |

##### Example successful response:
```json
{"brunch": {}, "lunch": {}}
```

##### Example error response:
```json
{"error": "Error parsing date string: the input \"aaa\" can't be parsed as ISO 8601."}
```

### GET /next-period
Returns a [`PeriodObj`](https://github.com/GunnWATT/watt/blob/main/docs/types.md#periodobj) corresponding to the next or
current period, the period immediately before it, and additional information for displaying those periods.
Expand Down
75 changes: 75 additions & 0 deletions docs/types.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,81 @@ type Club = {
}
```
### Entry
An object representing a brunch or lunch menu item.
```ts
type Entry = {
serving?: {
serving_size_amount: string,
serving_size_unit: string
},
nutrition?: {
calories?: number,
g_fat?: number,
g_saturated_fat?: number,
g_trans_fat?: number,
mg_cholesterol?: number,
g_carbs?: number,
g_added_sugar?: number,
g_sugar?: number,
mg_potassium?: number,
mg_sodium?: number,
g_fiber?: number,
g_protein?: number,
mg_iron?: number,
mg_calcium?: number,
mg_vitamin_c?: number,
iu_vitamin_a?: number,
re_vitamin_a?: number,
mcg_vitamin_a?: number,
mg_vitamin_d?: number,
mcg_vitamin_d?: number,
},
ingredients?: string
}
```
#### Reference:
[`/client/src/contexts/MenuContext.ts`](https://github.com/GunnWATT/watt/blob/main/client/src/contexts/MenuContext.ts#L4-L32)
#### Specifications:
- `serving`?: An object containing the serving size and unit of the described item.
- `nutrition`?: An object containing general nutrition information about the described item.
- `ingredients`?: A string containing the ingredients of the described item.
#### Example:
```json
{
"serving": {
"serving_size_amount": "1",
"serving_size_unit": "package"
},
"nutrition": {
"calories": 90,
"g_fat": 2.5,
"g_saturated_fat": 0,
"g_trans_fat": 0,
"mg_cholesterol": 0,
"g_carbs": 17,
"g_added_sugar": 5,
"g_sugar": 5,
"mg_potassium": 40,
"mg_sodium": 90,
"g_fiber": 1,
"g_protein": 1,
"mg_iron": 0.7,
"mg_calcium": 10,
"mg_vitamin_c": 0,
"iu_vitamin_a": 0,
"re_vitamin_a": null,
"mcg_vitamin_a": null,
"mg_vitamin_d": null,
"mcg_vitamin_d": 0
},
"ingredients": "Honey Graham Crackers (WHOLE WHEAT FLOUR, ENRICHED FLOUR (WHEAT FLOUR, NIACIN, REDUCED IRON, VITAMIN B1 (THIAMIN MONONITRATE), VITAMIN B2 (RIBOFLAVIN), FOLIC ACID), SUGAR, VEGETABLE OIL (SOYBEAN AND/OR CANOLA), MOLASSES, HONEY, CORN SYRUP, CONTAINS 2% OR LESS OF LEAVENING (BAKING SODA, SODIUM ACID PYROPHOSPHATE, MONOCALCIUM PHOSPHATE), SALT, SOY LECITHIN.)"
},
```
### Staff
An object representing a staff member at Gunn.
Expand Down
12 changes: 11 additions & 1 deletion functions/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import express, {NextFunction, Request, Response} from 'express';
import 'express-async-errors';

// Utils
import {getAlternates, getDateParam, getNextPeriodOptsParams, StatusError} from './util/apiUtil';
import {getAlternates, getDateParam, getMenu, getNextPeriodOptsParams, StatusError} from './util/apiUtil';
import {getSchedule, getNextPeriod} from '@watt/shared/util/schedule';
import {getNextPeriodMessage} from './util/schedule';

Expand Down Expand Up @@ -51,6 +51,16 @@ app.get('/api/schedule', async (req, res) => {
return res.json(schedule);
});

// GET /api/menu
// Gets the brunch/lunch menu for the current or provided day as `{brunch: Entry | null, lunch: Entry | null}`.
// `Entry` - https://github.com/GunnWATT/watt/blob/main/client/src/contexts/MenuContext.ts#L4-L32
app.get('/api/menu', async (req, res) => {
const date = getDateParam(req);

const menu = (await getMenu()).menu[date.toFormat('MM-dd')] || {brunch: null, lunch: null};
return res.json(menu);
})

// GET /api/next-period
app.get('/api/next-period', async (req, res) => {
const data = await getAlternates();
Expand Down
8 changes: 8 additions & 0 deletions functions/src/util/apiUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {Request} from 'express';
import {DateTime} from 'luxon';
import admin from './adminInit';
import {Alternates} from '@watt/client/src/contexts/AlternatesContext';
import {Menu} from '@watt/client/src/contexts/MenuContext'


// Gets the alternates object from firestore, throwing a `ServerError` if it's missing.
Expand All @@ -11,6 +12,13 @@ export async function getAlternates() {
return doc.data() as Alternates;
}

// Gets the menu object from firestore, throwing a `ServerError` if it's missing.
export async function getMenu() {
const doc = await admin.firestore().collection('gunn').doc('menu').get();
if (!doc.data()) throw new ServerError('Menu document malformed or nonexistant.');
return doc.data() as Menu;
}

// Gets the requested `DateTime`, attempting to parse it from `req.query.date` if given and defaulting to `DateTime.now()`
// if not. Throws a `ClientError` if `req.query.date` is provided and invalid.
export function getDateParam(req: Request) {
Expand Down

0 comments on commit 0eb16c2

Please sign in to comment.