Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
55 changes: 55 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"version": "0.0.1",
"configurations": [
{
"name": "backend-migrated",
"runtimeExecutable": "C:\\Users\\EFESTWIN\\miniconda3\\envs\\csc\\python.exe",
"runtimeArgs": [
"-m",
"invoke",
"dev-migrated"
],
"port": 8000
},
{
"name": "frontend",
"runtimeExecutable": "npm",
"runtimeArgs": [
"--prefix",
"src/frontend",
"run",
"dev"
],
"port": 3000
},
{
"name": "frontend-migrated",
"runtimeExecutable": "cmd",
"runtimeArgs": [
"/c",
"set MONGODB_URI=mongodb://127.0.0.1:27018/csc&& set FASTAPI_URL=http://127.0.0.1:8000&& npm --prefix src/frontend run dev"
],
"port": 3000
},
{
"name": "frontend-migrated-3100",
"runtimeExecutable": "cmd",
"runtimeArgs": [
"/c",
"set MONGODB_URI=mongodb://127.0.0.1:27018/csc&& set FASTAPI_URL=http://127.0.0.1:8000&& set NEXTAUTH_URL=http://127.0.0.1:3100&& npm --prefix src/frontend run dev -- -p 3100"
],
"port": 3100,
"url": "http://127.0.0.1:3100"
},
{
"name": "frontend-migrated-8010",
"runtimeExecutable": "cmd",
"runtimeArgs": [
"/c",
"set MONGODB_URI=mongodb://127.0.0.1:27019/csc&& set FASTAPI_URL=http://127.0.0.1:8010&& set NEXTAUTH_URL=http://127.0.0.1:3100&& set NEXT_DIST_DIR=.next-3100&& npm --prefix src/frontend run dev -- -p 3100"
],
"port": 3100,
"url": "http://127.0.0.1:3100"
}
]
}
60 changes: 55 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
name: CI

# Every PR and push, and as the first stage of every release (release.yml).
# Guards what goes live (decision 8.114): pull requests to main, every release
# (release.yml calls this workflow) and manual runs. No run per push. The wider
# suite (tests/catalog, tests/grasshopper, slow tests) runs locally:
# `invoke test-all`, and `invoke test-release` before tagging.
#
# On a pull request the frontend and backend jobs run only when their paths
# changed; a release and a manual run always run every job. A skipped job
# counts as passed for a required check.

on:
pull_request:
push:
branches: [main, 'v-*']
branches: [main]
workflow_call:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
changes:
name: Changed paths
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
outputs:
backend: ${{ steps.result.outputs.backend }}
frontend: ${{ steps.result.outputs.frontend }}
steps:
- uses: dorny/paths-filter@v3
id: filter
if: github.event_name == 'pull_request'
with:
filters: |
backend:
- 'src/backend/**'
- 'tests/api/**'
- 'tests/conftest.py'
- 'requirements-dev.txt'
- 'pytest.ini'
frontend:
- 'src/frontend/**'
- id: result
run: |
if [ "${{ github.event_name }}" = pull_request ]; then
echo "backend=${{ steps.filter.outputs.backend }}" >> "$GITHUB_OUTPUT"
echo "frontend=${{ steps.filter.outputs.frontend }}" >> "$GITHUB_OUTPUT"
else
echo "backend=true" >> "$GITHUB_OUTPUT"
echo "frontend=true" >> "$GITHUB_OUTPUT"
fi

versions:
name: Versions agree
runs-on: ubuntu-latest
Expand All @@ -24,6 +68,8 @@ jobs:

backend:
name: Backend tests
needs: changes
if: needs.changes.outputs.backend == 'true'
runs-on: ubuntu-latest
services:
mongodb:
Expand All @@ -45,8 +91,9 @@ jobs:
src/backend/requirements.txt
src/backend/constraints.txt
- run: pip install -r requirements-dev.txt
# csc_sheetscan (local tool, heavy dependencies) is tested locally only
- run: python -m pytest tests -q --ignore=tests/csc_sheetscan
# the route tests only (decision 8.114); every xdist worker gets its own
# database on the service container
- run: python -m pytest tests/api -q -n auto
- name: Backend installs on Uberspace 7 without compiling
run: python -m invoke check-server-wheels

Expand All @@ -66,6 +113,8 @@ jobs:

frontend:
name: Frontend
needs: changes
if: needs.changes.outputs.frontend == 'true'
runs-on: ubuntu-latest
defaults:
run:
Expand All @@ -80,6 +129,7 @@ jobs:
- run: npm ci
- run: npx tsc --noEmit
- run: npm run lint
- run: npm test
- run: npm run build

grasshopper:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,12 @@ scripts/**/*.log
/logs/
# LOCAL DEVELOPMENT (invoke dev-backend): data, assets, logs
/.dev/
src/backend/.dev/
src/backend/logs/*.log

csc_deploy_key.pub
csc_deploy_key
csc_known_hosts

# Scraped external catalogue files (large binaries, not committed)
/scraped_sources/
17 changes: 17 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# AGENTS.md

Guidance for coding agents working in this repository.

## Agent skills

### Issue tracker

GitHub Issues on `digitaldesignunit/csc` via the `gh` CLI; external PRs are not a triage surface. See `docs/agents/issue-tracker.md`.

### Triage labels

Default vocabulary (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`); category labels (`bug`, `enhancement`, `frontend`, `backend`, `grasshopper-interface`, ...) stay as they are. See `docs/agents/triage-labels.md`.

### Domain docs

Single-context: `CONTEXT.md` at the root, decisions as one numbered log in `docs/adr/DESIGN_DECISIONS.md`. See `docs/agents/domain.md`.
84 changes: 84 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,90 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.6.0.0] - 2026-10-09

The 0.6 data model: datasets and permissions, a moderated lifecycle for every
record, provenance and lineage, server-side geometry, an evidence system for
material properties, exports, a revised web interface and a rebuilt Grasshopper
bridge. The design is recorded in `docs/adr/` (`DATA_MODEL_SPEC.md`, decisions
up to 8.125 in `DESIGN_DECISIONS.md`, the phase plan in
`IMPLEMENTATION_PLAN_0.6.md`); the glossary is `CONTEXT.md`.

**Breaking.** The database is migrated once at the cutover (spec section 8,
`scripts/db_maintenance/migrate_06.py`); 0.5 clients are refused with 426
(`CSC_MIN_CLIENT_VERSIONS`), so Grasshopper users run `CSC_Update` (twice: the
0.5 updater installs the 0.6 UserObjects, the new one the `csc_gh` library) and
restart Rhino.

### Added

- **Datasets and memberships** with the roles contributor, reviewer and
moderator per dataset; visibility `members` (default) or `catalog`; public
pieces (`is_public`) for anonymous readers, who never see people (public tier).
Invitations bound to one address, the member editor by email, the admin user
list with filters.
- **Lifecycle for snapshots and evidence**: draft, pending, published,
rejected, withdrawn; recall, reinstate, purge with a 410 stub. Nobody publishes
directly: submitting moves a record to the moderation queue for every role, and
a moderator may publish their own record from the queue. Published claims are
frozen; a correction is a new record that supersedes the old one and keeps its
place in the version order. An empty capture field can be filled once.
- **Submit and edit in the web**: My work submits own drafts, snapshots and
evidence together (a refusal does not stop the others); a draft of evidence, or
for a moderator a pending one, is edited in the evidence form.
- **Change history** (`/changes`, `?as_of=`) for every record.
- **Provenance and lineage**: origin (incl. planned and in-place pieces with
deinstallation), exit and earlier cycles, cuts and merges with inherited fields,
DIN SPEC 91484 / DGNB fields, a managed `materials` list with waste-code
classes, batches with draws and the remaining quantity.
- **Geometry runner** (`main_geometry.py`): canonical frame, shape class,
fitted proxies (box, planar / linear prism, cylinder, hull) with deviation
maps, descriptors incl. heat kernel signatures, complexity and previews; stage
stamps make every result reproducible and stale on change. It also runs on
another machine (`--remote`), with a result cache (`--cache-dir`).
- **Evidence** (`component_evidence`): rebound hammer, cores, visual
inspection, reinforcement layout, documents and further methods, positioned on
the piece; verification with four eyes; attachments; a properties card folded
from all published evidence; one timeline for versions, cycles and evidence.
- **Exports**: component passport as JSON-LD (`compose?format=jsonld`,
`/context/v1.jsonld`), CERO for concrete and aerated concrete pieces and a PDF passport.
- **Web**: new component, cut, record new state and correct in one form; scan
path for unknown tags; component page with History (list / graph), Actions
menu and evidence; Browse as cards or table; My work; moderation tabs; the
component map coloured by shape class, dataset, material or circulation;
analytics; a generated reference of every Grasshopper component on the GH page.
- **Grasshopper**: shared library `csc_gh` installed by `CSC_Update`, declared
outputs, builders for actor, origin, metadata and capture, reinforcement
layout and generic evidence, bake to and sync with the Rhino document, D2P
bridge. Everything written from Grasshopper lands as a draft; completing and
submitting it happens in the web (My work).
- **Accounts**: password reset by mail; a password change signs out every other
session. Failed invitation mails are shown with Resend.
- `invoke rehearse`, `invoke dev-migrated`, `invoke test-changed / test-all /
test-release`, `check_invariants.py`.

### Changed

- Snapshot files (previews, photos, meshes, point clouds, proxies, capture
fixtures) are served only through the checked API routes; on the server they
move out of the web root (`~/csc_assets_private/`).
- Mails: one template with the `[CSC]` subject prefix, a `Reply-To` of the
acting moderator for invitations and member notices, sent off the event loop.
- Rate limits are keyed per token or per trusted client address
(`CSC_TRUSTED_PROXIES`, `CSC_PROXY_HOPS`).
- CI runs the API, frontend and deployment checks; the full suite runs locally
(`invoke test-all`, decision 8.114).

### Removed

- Designs (archived at the cutover), the 0.5 snapshot fields (`type`,
`extrusions`, `condition`, `validated`, `pca_frame`, ...), the 0.5 add-component
wizard, the orientation utility route and the separate descriptor and preview
cron jobs.
- `API_SECRET` in the frontend environment (never read); `NEXTAUTH_SECRET` is
independent of the backend's `JWT_SECRET`.


## [0.5.1.0] - 2026-09-28

Pre-work for the 0.6 data model: runtime, releases and deployment, client
Expand Down
Loading
Loading