Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6cc8cc8
Endpoint tester UI, tenant diagnostics, env-var credentials, GH issue…
grace-shane Apr 7, 2026
79eefa2
feat: .env.local loader + Claude Preview launch config (#14)
grace-shane Apr 7, 2026
7892923
fix: surface HTTP errors instead of swallowing them as None (#15)
grace-shane Apr 7, 2026
bd60221
docs: correct subscription-not-tenant hypothesis, add access matrix (…
grace-shane Apr 7, 2026
c88fb09
feat: production write guard at the proxy (#17)
grace-shane Apr 7, 2026
d242980
feat: migrate to PROD Plex environment + verified Grace tenant (#18)
grace-shane Apr 7, 2026
ef3239b
feat: run_dev.py local launcher (overrides shell env from .env.local)…
grace-shane Apr 7, 2026
e799c0b
docs: Plex tooling lives in inventory/v1/inventory-definitions/supply…
grace-shane Apr 7, 2026
cd1a8e4
feat: extract_supply_items + Fusion testing-harness endpoints (#21)
grace-shane Apr 7, 2026
249841d
fix: stdout UTF-8 reconfigure + ASCII arrows so prints don't crash Fl…
grace-shane Apr 7, 2026
8360b60
docs: end-of-session wrap-up — README rewrite + CLAUDE memory file (#23)
grace-shane Apr 7, 2026
fd35d99
docs: move long-form docs into docs/, add validate_library spec, giti…
grace-shane Apr 8, 2026
4220177
docs: fix stale content drift in BRIEFING, Plex_API_Reference, TODO, …
grace-shane Apr 8, 2026
f6fd672
docs(briefing): add 2026-04-08 session log, reorder Immediate TODO ar…
grace-shane Apr 8, 2026
fc448d1
feat(validate): implement validate_library.py pre-sync gate (#25) (#28)
grace-shane Apr 8, 2026
fb66865
docs: add Notion pointer + session protocol to BRIEFING and CLAUDE (#29)
grace-shane Apr 8, 2026
c662642
docs: rewrite README for April 2026 Supabase pivot + validate_library…
grace-shane Apr 8, 2026
494669b
feat(supabase): fusion2plex_* staging layer + Fusion JSON ingest (clo…
grace-shane Apr 8, 2026
644892b
docs: rename Fusion2Plex -> Datum, update repo URLs, log key rotation…
grace-shane Apr 9, 2026
197653a
refactor(supabase): drop fusion2plex_ prefix, use bare table names (#34)
grace-shane Apr 9, 2026
5a7e644
db: add 0001_initial_schema.sql for Datum project replay (#35)
grace-shane Apr 9, 2026
7f7a945
docs: full Postman collection catalog + reference doc (#38)
grace-shane Apr 9, 2026
066d70e
docs: 2026-04-09 Plex connectivity sweep + cross-ref findings (#39)
grace-shane Apr 9, 2026
75a07ff
chore: gitignore .claude/settings.local.json (#40)
grace-shane Apr 9, 2026
9e088b5
feat(web): React UI scaffold — tool browser, detail view, libraries (…
grace-shane Apr 10, 2026
1491e9c
docs: Classic Web Services discovery + scheduling/v1/jobs deep-dive (…
grace-shane Apr 10, 2026
1ffc091
feat: APS cloud tool library integration — no local Fusion needed (#4…
grace-shane Apr 10, 2026
fb737a5
feat: nightly sync CLI entrypoint + pyproject.toml packaging (#9) (#44)
grace-shane Apr 10, 2026
560c092
fix: bootstrap.py walks parent chain to find .env.local (#36) (#45)
grace-shane Apr 10, 2026
705ff2b
feat: add --log-file flag to sync.py for persistent nightly logs (#46)
grace-shane Apr 10, 2026
3aade28
fix: handle empty/corrupt JSON in loader + deploy nightly sync (#10, …
grace-shane Apr 10, 2026
90ab9ed
feat: vendor reference catalog + geometry-based tool enrichment (#48)
grace-shane Apr 10, 2026
6b726b7
feat: wire enrichment upstream in sync pipeline (#54)
grace-shane Apr 10, 2026
49062e7
feat: UI improvements — library tab, type dropdown, unit toggle, type…
grace-shane Apr 10, 2026
2d4a3fc
feat: UI round 2 — sortable headers, multi-filter, default inches, li…
grace-shane Apr 10, 2026
47b2abd
fix: UI polish — proper dropdown, Fusion Hub timestamps, recent page,…
grace-shane Apr 10, 2026
2543960
feat: Scripts page — Fusion 360 script to fix missing tool descriptio…
grace-shane Apr 10, 2026
f78fad8
deploy: SPA fallback + TS deprecation shim for Cloudflare Pages (#68)
grace-shane Apr 15, 2026
ba96eea
deploy: wrangler.jsonc for Workers Static Assets (SPA) (#70)
grace-shane Apr 15, 2026
abff6da
feat(ui): tab title "Datum" + bullseye favicon, Scripts page select a…
grace-shane Apr 15, 2026
bf00c64
feat(ui): last-sync indicator on Libraries page (#71) (#73)
grace-shane Apr 15, 2026
4ee5201
feat(db): add Plex linkage provenance + qty cache columns to tools (#…
grace-shane Apr 15, 2026
ce75615
feat(sync): tool inventory qty sync (Plex -> Supabase) — #75 (#78)
grace-shane Apr 15, 2026
b17cd69
feat(db): plex_supply_items staging table (#79/#80/#81 prereq) (#82)
grace-shane Apr 15, 2026
be4c682
Sprint: Plex staging pipeline + qty UI + Build a Library (#79/#76/#80…
grace-shane Apr 16, 2026
c1f363c
docs: refresh stale content — #25 closed, Phase 5 shipped, APS primar…
grace-shane Apr 17, 2026
570b9ac
feat(infra): GCP provisioning scripts + migration/reorg plans (#86)
grace-shane Apr 17, 2026
2fd45e4
feat(infra): secret-populate script + next-session prompts (#88)
grace-shane Apr 17, 2026
a90a0e9
feat(infra): Cloud Scheduler start/stop for datum-dev (#89)
grace-shane Apr 17, 2026
5414d28
fix(db): anon SELECT policy for plex_supply_items (#81 close-out) (#90)
grace-shane Apr 17, 2026
40c6199
fix(ui): bump main tool table corner radius (#83) (#91)
grace-shane Apr 17, 2026
75e50c0
docs(todo): Plex writes ship last, behind Plex-mimic mock (#92) (#93)
grace-shane Apr 17, 2026
146dd9f
feat(ui): add Corner R column to main tool table (before On hand) (#94)
grace-shane Apr 17, 2026
f415eb1
docs(plan): Plex-mimic mock HTTP server implementation plan (#92) (#95)
grace-shane Apr 17, 2026
98292be
feat(plex-mock): Plex-mimic HTTP server for write-pipeline validation…
grace-shane Apr 17, 2026
8138d67
fix(plex-mock): #96 review follow-ups — malformed bodies, write-guard…
grace-shane May 1, 2026
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
17 changes: 17 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "plex-api",
"runtimeExecutable": "py",
"runtimeArgs": ["run_dev.py"],
"port": 5000
},
{
"name": "web",
"runtimeExecutable": "npx",
"runtimeArgs": ["--prefix", "web", "vite", "web", "--port", "5174"],
"port": 5174
}
]
}
45 changes: 45 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# .env.example
#
# Copy this file to .env.local (which is gitignored) and fill in real values.
# bootstrap.py loads .env.local at startup so you don't have to set these
# variables in every shell. Real shell environment variables always win
# over .env.local via setdefault semantics.
#
# Get your Consumer Key and Consumer Secret from:
# https://developers.plex.com/ → My Apps → Fusion2Plex → Key

# ── REQUIRED ────────────────────────────────────────────────────────
PLEX_API_KEY=your-consumer-key-here
PLEX_API_SECRET=your-consumer-secret-here

# ── OPTIONAL ────────────────────────────────────────────────────────
# Override the target tenant. Defaults to the verified Grace Engineering
# production tenant. Set this only if you need to point at a different
# tenant for testing.
# PLEX_TENANT_ID=58f781ba-1691-4f32-b1db-381cdb21300c

# Hit the test environment (test.connect.plex.com) instead of production
# (connect.plex.com). The Fusion2Plex app currently only exists in
# production, so leaving this unset is correct for normal use.
# PLEX_USE_TEST=1

# Allow mutating HTTP methods (POST/PUT/PATCH/DELETE) against production.
# OFF by default — every write to connect.plex.com affects real Grace
# manufacturing data. Set to 1 only when you intentionally want to write,
# and unset it as soon as you're done.
# PLEX_ALLOW_WRITES=1

# ── SUPABASE — Datum ingest layer (issue #31) ──────────────────────
# Dedicated `datum` project. Service role key bypasses RLS and is
# used by sync_supabase.py to populate the libraries, tools, and
# cutting_presets tables. NEVER ship the service role key to a browser.
SUPABASE_URL=https://<your-datum-project-ref>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-jwt-here

# ── AUTODESK PLATFORM SERVICES (APS) — cloud tool libraries ──────
# Register an app at https://aps.autodesk.com → Applications → Create.
# App type: "Traditional Web App". Enable API: Data Management.
# Required scopes: data:read
APS_CLIENT_ID=your-aps-client-id-here
APS_CLIENT_SECRET=your-aps-client-secret-here
# APS_CALLBACK_URL=http://localhost:5000/api/aps/callback
33 changes: 33 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: tests

on:
pull_request:
branches: [master]
push:
branches: [master]

jobs:
test:
name: pytest
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt

- name: Run pytest
run: pytest
47 changes: 47 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
__pycache__/
*.pyc

# dotenv — local secrets, NEVER commit
.env
.env.local
.env.*.local

# APS OAuth tokens — local-only, contains access/refresh tokens
.aps_tokens.json

# Node / frontend
node_modules/

# editor / IDE
.vscode/
.idea/
*.swp

# Python tooling
.pytest_cache/
.coverage
htmlcov/
.tox/
*.egg-info/
build/
dist/

# Large reference material (kept locally, not in git)
data/

# Runtime outputs (regenerated by extractors, not source of truth)
outputs/

# Claude Code worktree scratch space
.claude/worktrees/

# Ad-hoc probe scripts, one-off dumps, and similar throwaway work
scratch/

# Claude Code per-machine permissions cache (regenerated on demand)
.claude/settings.local.json

# Plex mock — ephemeral capture data (POSTs the sync sent against the mock)
tools/plex_mock/captures/
tools/plex_mock/*.db
tools/plex_mock/*.db-journal
94 changes: 94 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Claude memory file

This is the entry point for Claude Code (or any AI agent) working on this
repository. **Read these files in this order before doing anything**:

1. **[`docs/BRIEFING.md`](./docs/BRIEFING.md)** — primary context document. Project
purpose, current credentials, current Plex environment, verified
endpoint matrix, gotchas, immediate TODO, "History of incorrect
hypotheses" postmortem, and a session log of what's been done. **This
is the most important file in the repo for AI context.**

2. **[`docs/Plex_API_Reference.md`](./docs/Plex_API_Reference.md)** — verified URL
patterns, the 401-vs-404 reading guide, and the no-pagination gotcha.
Read this before writing any new Plex API call.

3. **[`docs/Fusion360_Tool_Library_Reference.md`](./docs/Fusion360_Tool_Library_Reference.md)**
— Fusion JSON schema and field-to-Plex mapping. Read this before
writing anything that consumes the local Fusion library files.

4. **[`docs/Postman_Collections.md`](./docs/Postman_Collections.md)** —
the two Postman collections (Plex API — Datum and Fusion 360 Tool
Libraries — Datum), including the full endpoint catalog with
verified-vs-probe status, the `[NS]` naming convention, the safe
write workflow, and how to add new requests via the Postman MCP.
Read this before touching the collections or before exploring a new
Plex namespace from the Postman UI.

5. **[`TODO.md`](./TODO.md)** — project roadmap, links to GitHub Issues
for live status.

6. **Datum Notion page** — https://www.notion.so/Grace-Engineering-Fusion2Plex-33c3160a3abf81f1aac0e58101952be5
— **read at the start of every session.** Current State block tells
you phase, next action, and test count. End each session by updating
that block + appending one line to the Decision Log. See the
"Notion pages" section in `docs/BRIEFING.md` for details.

7. **Supabase staging layer** — Fusion JSON is ingested into the
`libraries`, `tools`, and `cutting_presets` tables in the dedicated
`datum` Supabase project (us-east-2) before anything pushes to Plex.
Schema spec: [Notion · Supabase Schema Design](https://www.notion.so/33c3160a3abf814c885cc174cda76d17).
Code: `supabase_client.py`, `sync_supabase.py`, `scripts/load_sample.py`.
Credentials: `SUPABASE_URL` + `SUPABASE_SERVICE_ROLE_KEY` in `.env.local`.
Issue #31. Downstream (`build_supply_item_payload`, #3) reads from
the `tools` table, not raw JSON.

## Hard rules

- **Never read credentials from images.** Always have the user paste them
as text or via Insomnia "Generate Code" output. We learned this the
hard way (see BRIEFING.md "History of incorrect hypotheses §1").
- **Never hardcode credentials.** They live in `.env.local` (gitignored),
loaded by `bootstrap.py`. Production deploy uses real shell env vars.
- **Never bypass the production write guard.** Mutating HTTP methods on
`connect.plex.com` are refused at `/api/plex/raw` unless
`PLEX_ALLOW_WRITES=1` is explicitly set in the environment.
- **Always run `pytest` before committing.** Branch protection on master
requires the `pytest` GitHub Actions check to pass before any merge.
- **Use the `claude/<short-name>` branch naming convention** for new
branches off master, then auto-merge with `gh pr merge --auto --squash`.
- **Never ship the Supabase service role key to a browser.** It bypasses
RLS. Server-side ingest scripts only.

## Quick commands

```powershell
# Run the local endpoint tester (overrides shell env from .env.local)
py run_dev.py

# Run tests
py -m pytest

# Open a PR with auto-merge
gh pr create --base master --head claude/my-branch --title "..." --body "..."
gh pr merge <number> --auto --squash
```

## Things this repo does NOT have

- A test environment for the Datum Plex app — production is the
only environment we have credentials for. Be cautious.
- A CI badge or release versioning yet
- Any tooling-API endpoints — Plex's tool data lives under
`inventory/v1/inventory-definitions/supply-items`, NOT
`tooling/v1/*` or `mdm/v1/parts`. See BRIEFING.md.

## When in doubt

- The repo is small and the context fits in one read of BRIEFING.md +
Plex_API_Reference.md. Read them; don't guess.
- Claude Code has a built-in `tenant_whoami` diagnostic at
`/api/diagnostics/tenant` — run that first whenever the connection
state is unclear.
- Open a PR. CI is fast (~10s) and branch protection guarantees you
can't break master.
87 changes: 0 additions & 87 deletions Plex_API_Reference.md

This file was deleted.

Loading