Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read # Required for Claude to read CI results on PRs
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

# Optional: Customize the trigger phrase (default: @claude)
# trigger_phrase: "/claude"

# Optional: Trigger when specific user is assigned to an issue
# assignee_trigger: "claude-bot"

# Optional: Configure Claude's behavior with CLI arguments
# claude_args: |
# --model claude-opus-4-1-20250805
# --max-turns 10
# --allowedTools "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
# --system-prompt "Follow our coding standards. Ensure all new code has tests. Use TypeScript for new files."

# Optional: Advanced settings configuration
# settings: |
# {
# "env": {
# "NODE_ENV": "test"
# }
# }
41 changes: 34 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Factory Inventory Management System Demo with GitHub integration - Full-stack application with Vue 3 frontend, Python FastAPI backend, and in-memory mock data (no database).

> ⚠️ **This repository and any fork you create are PUBLIC.** Do not commit credentials, internal hostnames, or private registry URLs. `client/.npmrc` pins the public npm registry and `client/package-lock.json` is gitignored to prevent locally-configured registries from leaking into commits — leave both in place.
Expand All @@ -26,7 +28,7 @@ Use the Task tool with these specialized subagents for appropriate tasks:
- Test against: `http://localhost:3000` (frontend), `http://localhost:8001` (API)

## Stack
- **Frontend**: Vue 3 + Composition API + Vite (port 3000)
- **Frontend**: Vue 3 + Composition API (Options-style `setup()`) + Vue Router + Vite (port 3000)
- **Backend**: Python FastAPI (port 8001)
- **Data**: JSON files in `server/data/` loaded via `server/mock_data.py`

Expand All @@ -42,29 +44,54 @@ cd client
npm install && npm run dev
```

## Key Patterns
## Running Tests

```bash
cd tests
uv run pytest -v # all tests
uv run pytest backend/test_inventory.py -v # one file
uv run pytest backend/test_inventory.py::TestInventoryEndpoints::test_get_all_inventory -v # one test
```

## Architecture

**Filter System**: 4 filters (Time Period, Warehouse, Category, Order Status) live in the `useFilters` composable (`client/src/composables/useFilters.js`) as module-level refs — a singleton shared across every view. `getCurrentFilters()` maps this state to API query params.

**Filter System**: 4 filters (Time Period, Warehouse, Category, Order Status) apply to all data via query params
**Data Flow**: Vue filters → `client/src/api.js` → FastAPI → In-memory filtering → Pydantic validation → Computed properties
**Reactivity**: Raw data in refs (`allOrders`, `inventoryItems`), derived data in computed properties
**Data Flow**: Vue filters (`useFilters`) → `client/src/api.js` → FastAPI query params → `apply_filters`/`filter_by_month` in `server/main.py` → Pydantic response models → Vue computed properties.

**Reactivity**: Raw data in refs (`allOrders`, `inventoryItems`), derived data in computed properties.

**i18n**: `useI18n` composable (`client/src/composables/useI18n.js`) drives translations from `client/src/locales/{en,ja}.js`. Locale also determines currency (`en` → USD, `ja` → JPY); use `formatCurrency`/`convertAmount` from `client/src/utils/currency.js` rather than formatting amounts inline. Locale persists to `localStorage` under `app-locale`.

**Auth**: `useAuth` composable (`client/src/composables/useAuth.js`) is fully mocked — a hardcoded current user, `isAuthenticated` always `true`, `logout()` just alerts. Task list in `App.vue` merges this mock user's tasks with real ones fetched via the API.

**Mock data lifecycle**: JSON in `server/data/*.json` is loaded once into module-level Python lists in `server/mock_data.py` at import time. All mutations during a server run are in-memory only; restarting the server reloads from disk.

## API Endpoints
- `GET /api/inventory` - Filters: warehouse, category
- `GET /api/orders` - Filters: warehouse, category, status, month
- `GET /api/inventory/{item_id}`
- `GET /api/orders` - Filters: warehouse, category, status, month (accepts `YYYY-MM` or `QN-YYYY` quarters)
- `GET /api/orders/{order_id}`
- `GET /api/dashboard/summary` - All filters
- `GET /api/demand`, `/api/backlog` - No filters
- `GET /api/spending/*` - Summary, monthly, categories, transactions
- `GET /api/reports/quarterly`, `/api/reports/monthly-trends` - Computed on the fly from `orders`, not filterable

**Known gap**: `client/src/api.js` also calls `/api/tasks` (GET/POST/PATCH/DELETE) and `/api/purchase-orders` (GET/POST) — these have no matching routes in `server/main.py`. Calls to them will 404 until implemented.

## Common Issues
1. Use unique keys in v-for (not `index`) - use `sku`, `month`, etc.
2. Validate dates before `.getMonth()` calls
3. Update Pydantic models when changing JSON data structure
3. Update Pydantic models in `server/main.py` when changing JSON data structure in `server/data/`
4. Inventory filters don't support month (no time dimension)
5. Revenue goals: $800K/month single, $9.6M YTD all months
6. `Backlog.vue` exists under `client/src/views/` but is not registered in `client/src/main.js` router

## File Locations
- Views: `client/src/views/*.vue`
- Composables: `client/src/composables/*.js` (`useFilters`, `useAuth`, `useI18n`)
- API Client: `client/src/api.js`
- Router: `client/src/main.js`
- Backend: `server/main.py`, `server/mock_data.py`
- Data: `server/data/*.json`
- Styles: `client/src/App.vue`
Expand Down
Loading