🎉 initial commit
This commit is contained in:
Generated
+10
@@ -0,0 +1,10 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Ignored default folder with query files
|
||||||
|
/queries/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/Ghost_Kitchen.iml" filepath="$PROJECT_DIR$/.idea/Ghost_Kitchen.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
# Ghost Kitchen
|
||||||
|
|
||||||
|
A web app for ordering food that is physically prepared by automated cooking hardware — no human staff cooks the food.
|
||||||
|
|
||||||
|
## Language
|
||||||
|
|
||||||
|
**Ghost Kitchen**:
|
||||||
|
A food-ordering venue with no human kitchen staff. Orders placed through the web app trigger automated cooking hardware on-site to prepare the food.
|
||||||
|
_Avoid_: Dark kitchen, cloud kitchen (these terms conventionally mean staffed, delivery-only kitchens — a different concept from this project's fully automated model)
|
||||||
|
|
||||||
|
**Kitchen**:
|
||||||
|
One physical location: a single deployment with its own server, its own database, one Brand, and its own set of cooking machines. Kitchens do not share a server or database with each other.
|
||||||
|
_Avoid_: Store, location (as a separate multi-tenant concept — this project has no cross-kitchen data layer)
|
||||||
|
|
||||||
|
**Brand**:
|
||||||
|
The single restaurant concept (menu, name, branding) served by one Kitchen. One Brand per Kitchen — not a separate entity shared across multiple kitchens.
|
||||||
|
|
||||||
|
**Order**:
|
||||||
|
A customer's placed, paid request, containing one or more Order Items. An Order is complete only once every Order Item within it has been picked up.
|
||||||
|
|
||||||
|
**Order Item**:
|
||||||
|
A single menu item within an Order. Progresses through its own Preparation Steps independently of the other items in the same Order, and can be picked up separately from them. Cancellable with refund any time before its first Preparation Step begins; locked once that step starts.
|
||||||
|
_Avoid_: Line item (implies a billing-only concept; this also carries preparation/pickup state)
|
||||||
|
|
||||||
|
**Preparation Step**:
|
||||||
|
One stage of preparing an Order Item, requiring a Machine carrying a specific Machine Tag, with an estimated duration. An Order Item consists of one or more Steps performed in sequence — the next Step cannot begin until the previous one finishes. The customer can see their Order Item's full Step list, current queue position, and approximate time to completion.
|
||||||
|
_Avoid_: Stage (use Step consistently)
|
||||||
|
|
||||||
|
**Machine**:
|
||||||
|
A physical cooking hardware unit at a Kitchen (e.g. an oven, a grill), carrying one or more Machine Tags. A Kitchen may have multiple Machines carrying the same Tag, working in parallel.
|
||||||
|
|
||||||
|
**Machine Tag**:
|
||||||
|
A capability label on a Machine (e.g. "oven", "grill", "assembly") describing which Preparation Steps it's able to perform.
|
||||||
|
|
||||||
|
**Queue**:
|
||||||
|
The set of Preparation Steps awaiting a Machine carrying a given Machine Tag, ordered by turn. When such a Machine becomes idle, it takes the next eligible Step from that Tag's Queue.
|
||||||
|
|
||||||
|
**Operator**:
|
||||||
|
The human role attached to a Kitchen, responsible only for physically restocking ingredients and repairing machines. Never involved in cooking or fulfilling orders.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# One server and database per Kitchen
|
||||||
|
|
||||||
|
Even though this codebase is built as a reusable template deployed to many ghost-kitchen operators, each Kitchen runs its own independent server and database with exactly one Brand — there is no central multi-tenant backend or cross-kitchen data layer. We chose this over a shared multi-tenant SaaS backend because each Kitchen's server talks directly to that Kitchen's own microcontrollers/machines, and keeping deployments fully independent avoids coupling physical hardware control to a shared cloud service. The trade-off: no built-in cross-kitchen reporting or central admin — any future need for that requires a separate aggregation layer, not a schema change to this one.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Order Items are independent, not the Order
|
||||||
|
|
||||||
|
Preparation, queuing, pickup, and cancellation are all tracked per Order Item, not per Order. An Order is just a bundle that is "complete" once every Order Item in it has been picked up — but each Order Item cooks on its own Machine, becomes ready on its own, gets notified and picked up on its own, and can be cancelled on its own (locked only once its own first Preparation Step starts). We chose this over treating the Order as the atomic unit because items in the same order can have very different cook times (a pizza vs. a burger); forcing them to stay in lockstep would mean a finished item goes cold waiting on a slower one, or a customer loses the ability to cancel a not-yet-started item just because a sibling item already started cooking.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# Machine-Tag pool with dynamic assignment
|
||||||
|
|
||||||
|
Machines are grouped by capability (Machine Tag, e.g. "oven", "grill", "assembly") into a shared pool per tag, rather than a Preparation Step being pinned to one specific machine at order time. When a Step reaches the top of its tag's Queue, it is dynamically assigned to whichever Machine carrying that tag is idle. We chose dynamic pool assignment over static per-machine queues because a Kitchen can have multiple Machines of the same tag, and pinning a Step to a specific machine up front would let a customer's order sit stuck behind one busy oven while a sibling oven of the same tag sits idle.
|
||||||
Reference in New Issue
Block a user