Skip to content

Add Restocking view, submitted orders, and tasks API#85

Open
takoron wants to merge 2 commits into
beck-source:mainfrom
takoron:new_features
Open

Add Restocking view, submitted orders, and tasks API#85
takoron wants to merge 2 commits into
beck-source:mainfrom
takoron:new_features

Conversation

@takoron
Copy link
Copy Markdown

@takoron takoron commented May 19, 2026

Summary

Adds a Restocking feature end-to-end, plus a basic Tasks API.

Frontend

  • New Restocking.vue view (router + nav entry, EN/JA locales) with a budget slider that auto-selects items by priority.
  • Orders.vue now renders a "Submitted Orders" section above the existing orders table, populated from the new endpoint.
  • api.js exposes getSubmittedOrders / createSubmittedOrder.

Backend

  • GET/POST /api/submitted-orders — budget-validated restocking orders; the server computes total_value, max_lead_time_days, and expected_delivery.
  • GET/POST/DELETE/PATCH /api/tasks — simple task list with a toggle endpoint. Task IDs are prefixed task-… to avoid colliding with the frontend's hardcoded mock IDs.
  • InventoryItem gains a required lead_time_days field; all rows in inventory.json are seeded.

Data & docs

  • New empty seed files: server/data/submitted_orders.json, server/data/tasks.json.
  • docs/architecture.html — system architecture diagram.
  • Two dashboard screenshots at the repo root (reference, not yet linked from README).

Notes for review

  • The Tasks API exists in the backend but the matching frontend (TasksModal etc.) is not part of this PR — the endpoint is ready to be wired up.
  • Task model uses camelCase dueDate (matches an upcoming frontend) while the rest of the API stays snake_case — see inline comment in server/main.py.

🤖 Generated with Claude Code

Frontend
- New Restocking view with budget slider that auto-selects items by priority
- Orders view shows a "Submitted Orders" section above the existing orders table
- api.js exposes getSubmittedOrders / createSubmittedOrder
- en/ja locales: restocking section, nav entry, submitted-orders labels

Backend
- POST/GET /api/submitted-orders: budget-validated restocking orders with
  computed total_value, max_lead_time_days, and expected_delivery
- GET/POST/DELETE/PATCH /api/tasks: simple task list with toggle endpoint
- InventoryItem gains lead_time_days (seeded across all inventory rows)

Data + docs
- Empty seed files: server/data/submitted_orders.json, tasks.json
- docs/architecture.html: system architecture diagram
- Dashboard screenshots at repo root for reference

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 19, 2026 18:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new Restocking workflow (frontend view + submitted-order persistence in the in-memory backend) and introduces a basic Tasks API to support the existing/soon-to-be-wired UI, along with required inventory lead-time data.

Changes:

  • Added FastAPI endpoints for submitted restocking orders (GET/POST /api/submitted-orders) and tasks (GET/POST/PATCH/DELETE /api/tasks) plus new JSON seed files.
  • Introduced a new Restocking Vue view and enhanced Orders to display a “Submitted Orders” section backed by the new endpoint.
  • Extended inventory items with required lead_time_days and added an architecture documentation page.

Reviewed changes

Copilot reviewed 13 out of 15 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
server/mock_data.py Loads new submitted_orders.json and tasks.json fixtures into memory.
server/main.py Adds Pydantic models + new submitted-orders and tasks API routes; adds lead_time_days to InventoryItem.
server/data/tasks.json Adds empty seed list for tasks.
server/data/submitted_orders.json Adds empty seed list for submitted orders.
server/data/inventory.json Seeds lead_time_days on all inventory fixture rows.
docs/architecture.html Adds architecture + API/model documentation page.
client/src/views/Restocking.vue New restocking UI (budget slider + greedy selection + submit order).
client/src/views/Orders.vue Displays submitted orders above the existing orders table and fetches them from the API.
client/src/main.js Registers the new /restocking route.
client/src/locales/ja.js Adds nav + Orders/restocking localization strings (JA).
client/src/locales/en.js Adds nav + Orders/restocking localization strings (EN).
client/src/App.vue Adds nav link to the Restocking view.
client/src/api.js Adds getSubmittedOrders / createSubmittedOrder API client helpers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/main.py
Comment on lines +226 to +250
@app.post("/api/submitted-orders", response_model=SubmittedOrder, status_code=201)
def create_submitted_order(req: CreateSubmittedOrderRequest):
"""Create a new submitted restocking order from a list of items + budget."""
if not req.items:
raise HTTPException(status_code=400, detail="At least one item is required")

total_value = round(sum(it.quantity * it.unit_cost for it in req.items), 2)
if total_value > req.budget:
raise HTTPException(
status_code=400,
detail=f"Total value {total_value} exceeds budget {req.budget}"
)

max_lead = max(it.lead_time_days for it in req.items)
submitted_at = datetime.now()
expected_at = submitted_at + timedelta(days=max_lead)

new_id = str(len(submitted_orders) + 1)
order_number = f"RST-{submitted_at.year}-{int(new_id):04d}"

new_order = {
"id": new_id,
"order_number": order_number,
"items": [it.model_dump() for it in req.items],
"total_value": total_value,
Comment thread server/main.py
Comment on lines +239 to +245
max_lead = max(it.lead_time_days for it in req.items)
submitted_at = datetime.now()
expected_at = submitted_at + timedelta(days=max_lead)

new_id = str(len(submitted_orders) + 1)
order_number = f"RST-{submitted_at.year}-{int(new_id):04d}"

Comment thread server/main.py
Comment on lines +275 to +280
new_task = {
"id": f"task-{int(datetime.now().timestamp() * 1000)}",
"title": req.title.strip(),
"priority": req.priority,
"dueDate": req.dueDate,
"status": "pending",
Comment thread server/main.py
Comment on lines +220 to +301
@app.get("/api/submitted-orders", response_model=List[SubmittedOrder])
def get_submitted_orders():
"""Get all submitted restocking orders (newest first)."""
# Return a copy in reverse-chronological order without mutating storage.
return list(reversed(submitted_orders))

@app.post("/api/submitted-orders", response_model=SubmittedOrder, status_code=201)
def create_submitted_order(req: CreateSubmittedOrderRequest):
"""Create a new submitted restocking order from a list of items + budget."""
if not req.items:
raise HTTPException(status_code=400, detail="At least one item is required")

total_value = round(sum(it.quantity * it.unit_cost for it in req.items), 2)
if total_value > req.budget:
raise HTTPException(
status_code=400,
detail=f"Total value {total_value} exceeds budget {req.budget}"
)

max_lead = max(it.lead_time_days for it in req.items)
submitted_at = datetime.now()
expected_at = submitted_at + timedelta(days=max_lead)

new_id = str(len(submitted_orders) + 1)
order_number = f"RST-{submitted_at.year}-{int(new_id):04d}"

new_order = {
"id": new_id,
"order_number": order_number,
"items": [it.model_dump() for it in req.items],
"total_value": total_value,
"budget": req.budget,
"submitted_date": submitted_at.isoformat(timespec='seconds'),
"expected_delivery": expected_at.isoformat(timespec='seconds'),
"max_lead_time_days": max_lead,
"status": "Submitted",
}
submitted_orders.append(new_order)
return new_order

@app.get("/api/tasks", response_model=List[Task])
def get_tasks():
"""Get all user tasks created via the API (newest first)."""
# Reverse without mutating storage so newest entries surface first.
return list(reversed(tasks))

@app.post("/api/tasks", response_model=Task, status_code=201)
def create_task(req: CreateTaskRequest):
"""Create a new task. ID is prefixed with 'task-' so it cannot collide
with the frontend's hardcoded numeric mock task IDs (1-4 in useAuth.js)."""
if not req.title.strip():
raise HTTPException(status_code=400, detail="Title is required")
if req.priority not in ("high", "medium", "low"):
raise HTTPException(status_code=400, detail="Priority must be high, medium, or low")

new_task = {
"id": f"task-{int(datetime.now().timestamp() * 1000)}",
"title": req.title.strip(),
"priority": req.priority,
"dueDate": req.dueDate,
"status": "pending",
}
tasks.append(new_task)
return new_task

@app.delete("/api/tasks/{task_id}")
def delete_task(task_id: str):
"""Delete a task by ID."""
index = next((i for i, t in enumerate(tasks) if t["id"] == task_id), None)
if index is None:
raise HTTPException(status_code=404, detail="Task not found")
tasks.pop(index)
return {"success": True, "id": task_id}

@app.patch("/api/tasks/{task_id}", response_model=Task)
def toggle_task(task_id: str):
"""Toggle a task's status between 'pending' and 'completed'."""
task = next((t for t in tasks if t["id"] == task_id), None)
if task is None:
raise HTTPException(status_code=404, detail="Task not found")
task["status"] = "completed" if task["status"] == "pending" else "pending"
return task
Comment thread docs/architecture.html
<!-- ================= TECH STACK ================= -->
<section>
<h2>Tech Stack</h2>
<p class="section-sub">Pinned versions taken from package.json and pyproject.toml.</p>
Comment thread docs/architecture.html
Comment on lines +769 to +777
<td class="path">/api/purchase-orders</td>
<td>—</td>
<td>Create purchase order</td>
</tr>
<tr>
<td><span class="method get">GET</span></td>
<td class="path">/api/purchase-orders/{id}</td>
<td>—</td>
<td>Get PO by backlog item</td>
Comment thread docs/architecture.html
Comment on lines +793 to +800
<ul class="stack-list">
<li><span class="k">sku</span><span class="v">str</span></li>
<li><span class="k">name</span><span class="v">str</span></li>
<li><span class="k">category</span><span class="v">str</span></li>
<li><span class="k">warehouse</span><span class="v">str</span></li>
<li><span class="k">quantity_on_hand</span><span class="v">int</span></li>
<li><span class="k">reorder_point</span><span class="v">int</span></li>
<li><span class="k">unit_cost</span><span class="v">float</span></li>
- client: add prettier ^3.8.3 to devDependencies
- .claude: add debugger agent, vue-optimize skill, settings.json

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants