Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
946 commits
Select commit Hold shift + click to select a range
d0ecee7
feat(www): rebuild the homepage stats panel around a monthly activity…
simonvanlierde Jul 10, 2026
38ecce3
fix(app): stop the gallery from silently deleting images it cannot re…
simonvanlierde Jul 10, 2026
53551bf
style(app): format the gallery index-persistence test
simonvanlierde Jul 10, 2026
664dc51
fix(backend): map admin user-not-found to 404 and harden preference r…
simonvanlierde Jul 10, 2026
5e9167a
chore: rename to ReLab
simonvanlierde Jul 10, 2026
11de17b
refactor(backend): delete the unreachable product validators
simonvanlierde Jul 10, 2026
12cd085
perf(app): pause the LAN re-probe interval while the app is backgrounded
simonvanlierde Jul 10, 2026
08d155d
fix(auth): close token lifecycle gaps and revoke sessions before dele…
simonvanlierde Jul 10, 2026
bbda9db
fix(rpi_cam): stop healthy cameras flapping to offline
simonvanlierde Jul 10, 2026
4e038cb
fix(rpi_cam): don't bridge a mid-command disconnect across workers
simonvanlierde Jul 10, 2026
11b7c2a
fix(rpi_cam): always end the livestream when stopping a recording
simonvanlierde Jul 10, 2026
3b71039
style(rpi_cam): collapse two over-wrapped lines
simonvanlierde Jul 10, 2026
e6937eb
chore: clean up some more relab renames
simonvanlierde Jul 10, 2026
e719bba
fix(app): single-flight auth submits and unblock post-verify redirect
simonvanlierde Jul 10, 2026
2e8e2e5
fix(auth): repair three defects in the auth services layer
simonvanlierde Jul 10, 2026
5ddb4fd
fix(app): surface delete failures and reset mobile product paging
simonvanlierde Jul 10, 2026
363952a
test(reference_data): make three reference-data tests assert what the…
simonvanlierde Jul 10, 2026
561bc23
refactor(auth): address lane-19 low-priority findings
simonvanlierde Jul 10, 2026
458d9c2
refactor(reference_data): resolve the lane-20 low-severity findings
simonvanlierde Jul 10, 2026
1df1de8
feat(app): let new-product drafts set a type/material before first save
simonvanlierde Jul 10, 2026
23aa6cf
refactor(auth): single-source the session cookie names
simonvanlierde Jul 10, 2026
2595f2f
fix(app): resolve lane-21 product-screen defects and dedup routes
simonvanlierde Jul 10, 2026
45a84bd
refactor(app): share the product streaming-state derivation
simonvanlierde Jul 10, 2026
4d0bdc2
feat(auth): notify on OAuth link/unlink and welcome social signups
simonvanlierde Jul 10, 2026
bb9e7ad
fix(docs): clarify API integration advice and improve privacy content…
simonvanlierde Jul 10, 2026
65cd138
fix(backend): make the public-profile GET write-free
simonvanlierde Jul 10, 2026
2f2e294
fix(app): pause the local re-probe interval while the screen is unfoc…
simonvanlierde Jul 10, 2026
705943d
feat(auth): require step-up re-auth to unlink a social login
simonvanlierde Jul 10, 2026
e873602
feat(app): prompt for the current password when unlinking a social login
simonvanlierde Jul 10, 2026
d4f8e5a
feat(auth): make registration non-enumerable
simonvanlierde Jul 10, 2026
df327df
feat(app): stop auto-login after signup to keep registration non-enum…
simonvanlierde Jul 10, 2026
adce5a1
refactor(backend): dedup email notifications and image URL building
simonvanlierde Jul 10, 2026
dc05af4
refactor(www): split buildChart into layer helpers, exempt tests from…
simonvanlierde Jul 10, 2026
06ea8c6
test(e2e): drop copy-coupled ARIA snapshots from www and docs
simonvanlierde Jul 10, 2026
fdae59b
test(www): update e2e specs for renamed footer home link
simonvanlierde Jul 10, 2026
a4e4bc4
test(e2e): remove unused product-detail helpers from app suite
simonvanlierde Jul 10, 2026
5e7d933
test(e2e): fix app auth flows after non-enumerable signup + skip auth…
simonvanlierde Jul 10, 2026
c7f46bc
chore: bump pre-commit deps
simonvanlierde Jul 10, 2026
0dea541
test(e2e): harden RN Paper menu helper against measurement-collapse f…
simonvanlierde Jul 10, 2026
b8798b0
ci(pre-commit): parallelize brand assets and defer heavy checks to pr…
simonvanlierde Jul 10, 2026
c882267
test(e2e): match CI retry count locally for app suite
simonvanlierde Jul 10, 2026
64ba115
feat: Enhance documentation and improve user guidance
simonvanlierde Jul 12, 2026
24777f8
fix: standardize terminology for sign in and sign out across the appl…
simonvanlierde Jul 12, 2026
87536c3
test: add validation tests for rpi-cam metadata bounds and upload policy
simonvanlierde Jul 12, 2026
2bfa48c
refactor: clean up and optimize test mocks across various components
simonvanlierde Jul 12, 2026
d76f4da
refactor(backend): delete dead storage/config/runtime flexibility
simonvanlierde Jul 12, 2026
e3d7cf5
chore(deps): refresh backend base images and pinned toolchain
simonvanlierde Jul 12, 2026
dd3d63d
fix(ci): unblock trivy container security scans
simonvanlierde Jul 12, 2026
d785833
fix: resolve code-scanning findings on PR #159
simonvanlierde Jul 12, 2026
b8ec741
fix: resolve remaining CodeQL findings on PR #159
simonvanlierde Jul 12, 2026
b46384f
fix: update openapi-check to use testing environment for CI compatibi…
simonvanlierde Jul 13, 2026
98983da
fix(ci): unblock security and validate workflows
simonvanlierde Jul 13, 2026
30446be
fix(ci): auto-dismiss CodeQL alerts suppressed via in-code comments
simonvanlierde Jul 13, 2026
58a96ce
fix: update yaml dependency to version >=2.8.1 in lockfiles
simonvanlierde Jul 13, 2026
42fd446
perf(ci): cache container-security image layers via GHA cache
simonvanlierde Jul 13, 2026
0dcdc41
perf(ci): derive CodeQL language matrix from changed paths
simonvanlierde Jul 13, 2026
ee73c53
fix(app): move jest maxWorkers to root config so it applies
simonvanlierde Jul 13, 2026
d858f8c
chore: drop stale large-file exclude for removed EBGaramond font
simonvanlierde Jul 13, 2026
c1ef5b9
feat(assets): adopt cyanotype design system with IBM Plex superfamily
simonvanlierde Jul 13, 2026
eb4740a
feat(assets): replace flask logo with font-derived squished-9 pipeline
simonvanlierde Jul 13, 2026
7631733
feat(app): move MD3 theme to cyanotype palette
simonvanlierde Jul 13, 2026
1975e0f
feat(app): add BrandWordmark component for the login and onboarding h…
simonvanlierde Jul 13, 2026
13a7259
feat(www): use the ringed logo as the hero title and align theme-color
simonvanlierde Jul 13, 2026
6b80166
feat(docs): inline brand tokens from brand.css in the API reference page
simonvanlierde Jul 13, 2026
18f9464
feat(backend): tokenize email brand surface and divider colours
simonvanlierde Jul 13, 2026
bcd2849
feat(app): add nativewind v5 toolchain (metro, postcss, global.css)
simonvanlierde Jul 14, 2026
24ec62c
feat(assets): generate app cyanotype palette css + ts from palette.json
simonvanlierde Jul 14, 2026
20acae4
style: format palette.generated.ts with biome
simonvanlierde Jul 14, 2026
3491163
feat(assets): emit a theme-adaptive favicon and ship it to docs and www
simonvanlierde Jul 14, 2026
714d718
feat(www): adopt display and mono faces and cyanotype data colours
simonvanlierde Jul 14, 2026
7834e04
feat(docs): adopt the display and mono faces in site styles
simonvanlierde Jul 14, 2026
efb77d8
feat(docs): move architecture diagrams to the brand categorical ramp
simonvanlierde Jul 14, 2026
8331771
feat(app): apply the brand type scale to the paper theme
simonvanlierde Jul 14, 2026
8bd6464
docs(assets): document the diagram palette and trim the roadmap
simonvanlierde Jul 14, 2026
5240b58
feat(www): add local development environment
simonvanlierde Jul 14, 2026
85911d3
fix(app): keep generated palette artifacts generator-true and biome-e…
simonvanlierde Jul 14, 2026
2a6766a
refactor(app): derive md3 colors from canonical palette; add spacing/…
simonvanlierde Jul 14, 2026
2baec0a
fix(assets): correct light input token to the original outline value
simonvanlierde Jul 14, 2026
324b0bc
feat(app): add lg breakpoint, useBreakpoint hook, PageContainer scaffold
simonvanlierde Jul 14, 2026
bf7e9d0
feat(app): vendor rnr base components, add AppText/AppButton, sync co…
simonvanlierde Jul 14, 2026
f2c2cb2
docs(app): record nativewind + rnr foundation in architecture
simonvanlierde Jul 14, 2026
102673c
fix(app): guard color scheme sync against missing web Appearance API
simonvanlierde Jul 14, 2026
c0a58e1
fix(app): route AppButton labels through the button text context
simonvanlierde Jul 14, 2026
615311c
fix(app): re-assert native color scheme on OS changes; note phase-2 d…
simonvanlierde Jul 14, 2026
5e9de5c
feat(app): add Section and SpecFacts primitives; enable class-driven …
simonvanlierde Jul 14, 2026
b8f87b8
feat(app): add section nav registry hook and chips/outline component
simonvanlierde Jul 14, 2026
a160e6c
fix(app): let AppText default color yield to caller classNames
simonvanlierde Jul 14, 2026
54b36df
feat(app): add spec-sheet header for product identity and key facts
simonvanlierde Jul 14, 2026
d540ecd
test(app): assert size fact; document spec-utils as formatWeight home
simonvanlierde Jul 14, 2026
02667ae
feat(app): restructure detail screen into navigable spec-sheet sections
simonvanlierde Jul 14, 2026
48c0266
feat(app): elevate components section with expandable bill-of-materia…
simonvanlierde Jul 14, 2026
26406bc
feat(app): surface validation as fab error count with scroll-to-first…
simonvanlierde Jul 14, 2026
11f74b6
fix(app): update e2e fab assertions for error-count label; simplify g…
simonvanlierde Jul 14, 2026
5309370
docs(app): document section-nav detail architecture; update e2e for r…
simonvanlierde Jul 14, 2026
f62f5dd
fix(app): register section anchors in scroll-content coordinates
simonvanlierde Jul 14, 2026
de14a26
fix(app): keep overview visible for tagged records; guard fab edge st…
simonvanlierde Jul 14, 2026
8dea2a2
fix(app): dedupe section headings and stabilize bom row expansion
simonvanlierde Jul 14, 2026
7e61fc9
feat(app): add AmountStepper primitive
simonvanlierde Jul 14, 2026
8ae3bc7
feat(app): add capture-entity hook for minimal record creation
simonvanlierde Jul 14, 2026
64e1a88
feat(app): capture-first creation screen for products and components
simonvanlierde Jul 14, 2026
0047238
fix(app): rename capture role prop to entityRole; assert component ro…
simonvanlierde Jul 14, 2026
c716034
test(app): rewrite new-product e2e flows for capture-first creation
simonvanlierde Jul 14, 2026
2a0abdf
refactor(app): remove the legacy isNew full-form creation path
simonvanlierde Jul 14, 2026
101d19f
fix(app): guard capture screen for guests; cap name length
simonvanlierde Jul 14, 2026
a82da15
docs(app): document capture-first creation flow
simonvanlierde Jul 14, 2026
677c465
fix(app): invite type selection instead of rendering an undefined cat…
simonvanlierde Jul 14, 2026
f3eaa0f
fix(app): make the capture screen scrollable
simonvanlierde Jul 14, 2026
964e4b4
fix(app): recover from partial create failures without duplicating re…
simonvanlierde Jul 14, 2026
9f189e8
fix(app): invite type selection on the detail screen instead of an er…
simonvanlierde Jul 14, 2026
9c5d32f
fix(app): route batch partial-success creates to the detail screen
simonvanlierde Jul 14, 2026
02dc2ce
build(app): rebuild dist before e2e so stale exports cannot pass
simonvanlierde Jul 14, 2026
7676438
refactor(app): make the section nav registry screen-agnostic
simonvanlierde Jul 14, 2026
261cfd0
feat(app): define the grouped account section config
simonvanlierde Jul 14, 2026
b0b5b6d
feat(app): restructure the account screen into grouped sections
simonvanlierde Jul 15, 2026
3082bb2
feat(app): add desktop top nav and destination config
simonvanlierde Jul 15, 2026
13a05f3
fix(app): prefix-match active top-nav destination; correct brand casing
simonvanlierde Jul 15, 2026
01bef14
feat(app): mount desktop top nav and adopt the page scaffold across s…
simonvanlierde Jul 15, 2026
d78d679
fix(app): keep phone insets unchanged when adopting the page scaffold
simonvanlierde Jul 15, 2026
aa2616c
feat(app): add web hover, focus, and selection affordances to base pr…
simonvanlierde Jul 15, 2026
efe5ef8
test(app): mirror real web Platform.select in the mock; scope platfor…
simonvanlierde Jul 15, 2026
7fee6bb
fix(app): stop TopNav rendering over chrome-free auth screens
simonvanlierde Jul 15, 2026
321bc72
fix(app): fix account section anchors zeroed by the danger-zone wrapper
simonvanlierde Jul 15, 2026
47f43ce
feat(app): add focus trap and Escape-to-dismiss for dialogs
simonvanlierde Jul 15, 2026
ea2ca6b
docs(app): document account and web chrome; add account and top-nav e2e
simonvanlierde Jul 15, 2026
edf4ec2
feat(app): fold account stats into the hero header
simonvanlierde Jul 15, 2026
9014ce6
fix(app): hide top nav on mfa and category screens; restore dialog fo…
simonvanlierde Jul 15, 2026
b36b586
fix(app): add Linux environment variable for Electron sandbox in star…
simonvanlierde Jul 15, 2026
9e46586
feat: deduplicate pnpm version in Dockerfiles and bump to 11.13.0
simonvanlierde Jul 15, 2026
e9a53ef
chore(app): bump expo deps
simonvanlierde Jul 15, 2026
456c487
refactor(app): deliver the app theme without paper's context
simonvanlierde Jul 15, 2026
8a594d9
refactor(app): convert base primitives off react-native-paper
simonvanlierde Jul 15, 2026
7253e0e
refactor(app): convert the dialog and toast system off react-native-p…
simonvanlierde Jul 15, 2026
de53d92
refactor(app): convert fab, search, menus, and remaining controls off…
simonvanlierde Jul 15, 2026
3a91572
refactor(app): convert the product surfaces off react-native-paper
simonvanlierde Jul 15, 2026
50c5ed0
fix(app): restore filter-chip selected state and theme the go-live label
simonvanlierde Jul 15, 2026
f8048da
refactor(app): convert cameras, auth, and remaining surfaces off reac…
simonvanlierde Jul 15, 2026
440cd37
feat(app): show the cameras nav link only when rpi cameras are enabled
simonvanlierde Jul 15, 2026
ecdc652
refactor(app)!: remove react-native-paper
simonvanlierde Jul 15, 2026
87f60a2
test(app): fix e2e for the paper-free menu and conditional cameras nav
simonvanlierde Jul 15, 2026
cf6498a
refactor(app): drop the dead MD3 fonts scale from the theme
simonvanlierde Jul 15, 2026
2007ede
feat(assets): promote the Titillium mark and regenerate the brand ass…
simonvanlierde Jul 15, 2026
a4797fe
docs(assets): record Titillium as the promoted canonical mark
simonvanlierde Jul 15, 2026
63636c2
refactor(backend): use "Relab" consistently in copy, emails, and API …
simonvanlierde Jul 15, 2026
920a337
refactor(www): use "Relab" consistently in site copy and metadata
simonvanlierde Jul 15, 2026
0146ae9
refactor(docs): use "Relab" consistently in docs copy and metadata
simonvanlierde Jul 15, 2026
33c7176
refactor(app): use "Relab" consistently in app display name and copy
simonvanlierde Jul 15, 2026
55cafa3
refactor: use "Relab" in remaining root, infra, and brand text
simonvanlierde Jul 15, 2026
ea21a34
feat(www): add a short circular-economy explainer for the Relab name
simonvanlierde Jul 15, 2026
c818435
feat(app): add a tonal AppButton variant and restore softened CTAs
simonvanlierde Jul 15, 2026
e997920
refactor(app): extract a shared StatusPill for live and telemetry badges
simonvanlierde Jul 15, 2026
33a86ac
fix(app): stop rendering an undefined product type as an error card
simonvanlierde Jul 15, 2026
c514f1c
fix(app): meet the 44px touch floor and restore menu/spinner a11y state
simonvanlierde Jul 15, 2026
6135339
fix(app): dedupe the metadata heading and realign the detail skeleton
simonvanlierde Jul 15, 2026
73aac4f
fix(app): tier the products grid on the post-gutter content width
simonvanlierde Jul 15, 2026
627135a
fix(app): give product thumbnails accessible alt text
simonvanlierde Jul 15, 2026
4b359f4
refactor(app): dedupe dialog styles, retype the scroll ref, refresh s…
simonvanlierde Jul 15, 2026
50e20ce
docs(app): record the environmental e2e failures and their ops fix
simonvanlierde Jul 15, 2026
83387ef
refactor: rename ReLab -> Relab
simonvanlierde Jul 15, 2026
9eda34b
test(app): assert the Details section by its metadata content, not th…
simonvanlierde Jul 15, 2026
dff9634
chore: bump deps
simonvanlierde Jul 16, 2026
4f3eb94
fix(auth): handle malformed email addresses in get_by_email method
simonvanlierde Jul 16, 2026
da4ef12
test(auth): add test for get_by_email to return None for malformed email
simonvanlierde Jul 16, 2026
64c8b85
feat(auth): enhance LoginLayout for desktop support with responsive d…
simonvanlierde Jul 16, 2026
8bb3e7f
docs(assets): scope manila to accent text only; primary shades for bu…
simonvanlierde Jul 16, 2026
3efa69e
feat(app): add the flat & sharp radius, elevation, and scrim tokens
simonvanlierde Jul 16, 2026
9900f87
fix(scripts): set BROWSER to none for dev and web commands to prevent…
simonvanlierde Jul 16, 2026
49b14d6
feat(justfile): add dev-clean command to start server with cleared Me…
simonvanlierde Jul 16, 2026
97cf79c
chore: rotate light background images for better readability
simonvanlierde Jul 16, 2026
43eafbd
feat(auth): unify the auth screens on a shared centered island layout
simonvanlierde Jul 16, 2026
aeb9d82
feat(app): add a Lucide-backed Icon primitive with a curated name map
simonvanlierde Jul 16, 2026
3361ba9
docs(Icon): clean up comment prefixes and remove stale reference
simonvanlierde Jul 16, 2026
72b68ac
refactor(app): migrate base icons to the Lucide Icon primitive
simonvanlierde Jul 16, 2026
8609838
refactor(app): migrate auth icons to the Lucide Icon primitive
simonvanlierde Jul 16, 2026
78d8071
refactor(app): migrate product icons to the Lucide Icon primitive
simonvanlierde Jul 16, 2026
428ba01
refactor(app): migrate cameras icons to the Lucide Icon primitive
simonvanlierde Jul 16, 2026
29fa890
feat(app): cap and centre the last two full-bleed screens on desktop
simonvanlierde Jul 16, 2026
1e121af
refactor(app): migrate remaining route-level icons to the Lucide Icon…
simonvanlierde Jul 16, 2026
98c9cd7
fix(app): restore PageContainer wrap dropped by a stale commit base
simonvanlierde Jul 16, 2026
03da7a9
feat(app): migrate Menu trailing icon off MaterialCommunityIcons
simonvanlierde Jul 16, 2026
d00e11f
refactor(app): flatten buttons and stop manila leaking into interacti…
simonvanlierde Jul 16, 2026
0c53929
fix(app): repair the unsafe optional chaining that failed just check
simonvanlierde Jul 16, 2026
841f421
refactor(app): replace the new-account desktop breakpoint with an int…
simonvanlierde Jul 16, 2026
1e24787
fix(app): use primary tint state-layers for ghost and outline buttons
simonvanlierde Jul 16, 2026
df08882
refactor(app): flatten detail cards and tokenise the overlay surface …
simonvanlierde Jul 16, 2026
2556d6d
refactor(app): put chips and inputs on the control radius token
simonvanlierde Jul 16, 2026
28af62f
fix(app): treat mfa and verify as the hero auth screens they now are
simonvanlierde Jul 16, 2026
82aa7f4
refactor(app): give overlays the 12px radius and the single elevation…
simonvanlierde Jul 16, 2026
fe847cd
refactor(app): align StatusPill to the control radius
simonvanlierde Jul 16, 2026
edf3b99
refactor(app): drop input radius hardcodes and the manila fill on the…
simonvanlierde Jul 16, 2026
aef7280
fix(auth): put onboarding and the new-account footer on cards
simonvanlierde Jul 16, 2026
c60172c
fix(auth): rebuild the new-account step on a wizard action row and re…
simonvanlierde Jul 16, 2026
61fc21f
refactor(app): put the last bespoke radii on the shared tokens
simonvanlierde Jul 16, 2026
d9a361c
feat(auth): draw the hero scrim as a centre-weighted gradient
simonvanlierde Jul 16, 2026
26a477e
fix(auth): give every auth field a visible label
simonvanlierde Jul 16, 2026
9d3e120
fix(app): stop dialogs painting themselves with the backdrop scrim
simonvanlierde Jul 16, 2026
c0650b7
refactor(auth): align the new-account headline to the card and drop t…
simonvanlierde Jul 16, 2026
07a2040
fix(app): flatten inputs and stop the search icon overlapping its text
simonvanlierde Jul 16, 2026
00fd322
fix(app): keep anchored menus inside the viewport
simonvanlierde Jul 16, 2026
fc87c98
fix(app): stop the new-product fab dimming and relabelling for guests
simonvanlierde Jul 16, 2026
a35b986
fix(auth): scope the hero band to the two screens that need it, and d…
simonvanlierde Jul 16, 2026
b5f4bc5
refactor(app): move getMenuPosition out of the Menu component file
simonvanlierde Jul 16, 2026
d68ba83
fix(product): pad the capture screen and label the type row by role
simonvanlierde Jul 16, 2026
6edf2bf
build(www): adopt Tailwind v4 mapped to the Relab brand variables
simonvanlierde Jul 16, 2026
29678ab
fix(www): layer legacy CSS so Tailwind utilities can override it
simonvanlierde Jul 16, 2026
9910985
refactor(www): migrate ThemeControl and Hero to Tailwind utilities
simonvanlierde Jul 16, 2026
1417899
refactor(www): migrate SiteFooter to Tailwind utilities
simonvanlierde Jul 16, 2026
8c53a25
refactor(www): migrate ContentPage and privacy to Tailwind utilities
simonvanlierde Jul 16, 2026
3a63d27
refactor(www): apply the flat & sharp form language to site chrome
simonvanlierde Jul 16, 2026
f85a0d4
build(docs): adopt Tailwind v4 mapped to the Relab brand variables
simonvanlierde Jul 16, 2026
2dbd5af
fix(docs): drop Tailwind preflight, keep theme and utilities
simonvanlierde Jul 16, 2026
05f9984
refactor(docs): bring Starlight theming onto the flat & sharp form la…
simonvanlierde Jul 16, 2026
6a0b595
build(docs): drop Tailwind, keep the brand on plain CSS variables
simonvanlierde Jul 17, 2026
879f4ee
fix(docs): tokenize two hardcoded control radii to --radius-control
simonvanlierde Jul 17, 2026
3118360
docs(design): scope the manila accent to small text, ink for mass
simonvanlierde Jul 17, 2026
3fd5671
fix(auth): put the MFA screen on a card and label every code field
simonvanlierde Jul 17, 2026
15f1657
fix(product): label the type row by role from one shared source
simonvanlierde Jul 17, 2026
26ee144
refactor(app): use undefined, not NaN, for unset physical properties
simonvanlierde Jul 17, 2026
ea01a23
fix(product): scroll to the visually first invalid section
simonvanlierde Jul 17, 2026
10b9aa1
docs(profile): point the guard note at AccountScreen
simonvanlierde Jul 17, 2026
bceee23
fix(profile): label the recovery field in the turn-off dialog
simonvanlierde Jul 17, 2026
5815064
docs: record the data-scarcity motivation behind the platform
simonvanlierde Jul 18, 2026
1de826d
feat(www): add the landing data layer with a build-time fixture fallback
simonvanlierde Jul 18, 2026
3395143
feat(deploy): wire FEATURED_PRODUCT_ID into the www landing build
simonvanlierde Jul 18, 2026
3a7ec5e
feat(www): load the landing payload at build time
simonvanlierde Jul 18, 2026
8307baa
feat(www): replace the landing hero with a live teardown blueprint
simonvanlierde Jul 18, 2026
cf427c3
fix(www): make the example-teardown marker honest and fully tested
simonvanlierde Jul 18, 2026
0a4a8c9
feat(www): add the motivation section to the landing page
simonvanlierde Jul 18, 2026
1a55da0
feat(www): add the 9R ladder as the landing page's spine
simonvanlierde Jul 18, 2026
4557ccc
fix(www): keep a space before the 9R source citation link
simonvanlierde Jul 18, 2026
95a227a
feat(www): add the teardown-to-data method section
simonvanlierde Jul 18, 2026
3fb1a67
fix(www): keep list semantics on the ladder and method steps in WebKit
simonvanlierde Jul 18, 2026
55f9782
feat(www): refresh the landing metrics after load
simonvanlierde Jul 18, 2026
0484360
fix(www): keep list semantics on the hero parts and photo lists in We…
simonvanlierde Jul 18, 2026
224cec6
test(www): cover the rebuilt landing page end to end
simonvanlierde Jul 18, 2026
bcc940d
feat(www): default the public site URLs so builds work without env
simonvanlierde Jul 18, 2026
0062c60
feat(www): add a brand header with app, docs, and GitHub links
simonvanlierde Jul 18, 2026
51fae2d
feat(www): collapse the hero to a single dataset call to action
simonvanlierde Jul 18, 2026
5684844
feat(www): compact the 9R ladder and move full definitions to the docs
simonvanlierde Jul 18, 2026
d6494f2
feat(www): visualize part masses and subcomponents in the hero teardown
simonvanlierde Jul 18, 2026
df661d8
refactor(rpi-cam): simplify relay seam
simonvanlierde Jul 19, 2026
38af1ec
refactor(rpi-cam): use session context manager in websocket router
simonvanlierde Jul 19, 2026
eb2f493
feat(www): add the data-collection flowchart to the method section
simonvanlierde Jul 19, 2026
7953052
fix(www): widen the 9R lede and connect the framework to the platform
simonvanlierde Jul 19, 2026
44378fd
feat(www): lead the landing page with a brand hero
simonvanlierde Jul 19, 2026
80c36fd
docs: simplify docs
simonvanlierde Jul 19, 2026
23d4a58
chore: update biome
simonvanlierde Jul 19, 2026
b71ccf8
fix(rpi-cam): clean up stale circuit-breaker references after relay-s…
simonvanlierde Jul 19, 2026
e68a1ca
fix(design-compare): add button type attributes for accessibility
simonvanlierde Jul 19, 2026
01de0d2
fix(dependencies): update relab-rpi-cam-models to version 0.5.0
simonvanlierde Jul 19, 2026
a7d2181
fix(method-steps): update method flow imports to use components
simonvanlierde Jul 19, 2026
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
  •  
  •  
  •  
121 changes: 0 additions & 121 deletions .cspell.yaml

This file was deleted.

14 changes: 14 additions & 0 deletions .devcontainer/app/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "relab-app",
"dockerComposeFile": ["../../compose.yaml", "../../compose.dev.yaml"],
"service": "app",
"runServices": ["app"],
"workspaceFolder": "/opt/relab/app",
"mounts": ["source=${localWorkspaceFolder},target=/opt/relab,type=bind,consistency=cached"],
"overrideCommand": true,
"postAttachCommand": "echo 'Relab app devcontainer ready.\\nUse this for focused app work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nApp: http://127.0.0.1:8011'",
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers-extra/features/expo-cli:1": {}
}
}
2 changes: 1 addition & 1 deletion .devcontainer/backend/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"workspaceFolder": "/opt/relab/backend",
"mounts": ["source=${localWorkspaceFolder},target=/opt/relab,type=bind,consistency=cached"],
"overrideCommand": true,
"postAttachCommand": "echo 'RELab backend devcontainer ready.\\nUse this for focused backend work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nAPI: http://localhost:8011'",
"postAttachCommand": "echo 'Relab backend devcontainer ready.\\nUse this for focused backend work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nAPI: http://127.0.0.1:8010'",
"features": {
"ghcr.io/devcontainers/features/git:1": {}
},
Expand Down
6 changes: 3 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "relab-fullstack",
"dockerComposeFile": ["../compose.yaml", "../compose.dev.yaml"],
"service": "app-site",
"runServices": ["api", "redis", "postgres", "docs-site", "web-site", "app-site"],
"service": "app",
"runServices": ["api", "redis", "postgres", "docs", "www", "app"],
"workspaceFolder": "/opt/relab",
"mounts": ["source=${localWorkspaceFolder},target=/opt/relab,type=bind,consistency=cached"],
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers-extra/features/expo-cli:1": {},
"ghcr.io/jsburckhardt/devcontainer-features/uv:1": {}
},
"postAttachCommand": "echo 'RELab full-stack devcontainer ready.\\nPrimary workflow: run just install once, then use just dev / just ci from the repo root.\\nPlatform: http://localhost:8010\\nAPI: http://localhost:8011\\nDocs: http://localhost:8012\\nApp: http://localhost:8013'"
"postAttachCommand": "echo 'Relab full-stack devcontainer ready.\\nPrimary workflow: run just install once, then use just dev / just ci from the repo root.\\nAPI: http://127.0.0.1:8010\\nApp: http://127.0.0.1:8011\\nDocs: http://127.0.0.1:8012\\nLanding site: http://127.0.0.1:8013'"
}
6 changes: 3 additions & 3 deletions .devcontainer/docs/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "relab-docs",
"dockerComposeFile": ["../../compose.yaml", "../../compose.dev.yaml"],
"service": "docs-site",
"runServices": ["docs-site"],
"service": "docs",
"runServices": ["docs"],
"workspaceFolder": "/opt/relab/docs",
"mounts": ["source=${localWorkspaceFolder},target=/opt/relab,type=bind,consistency=cached"],
"postAttachCommand": "echo 'RELab docs devcontainer ready.\\nUse this for focused docs work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nDocs: http://localhost:8012'",
"postAttachCommand": "echo 'Relab docs devcontainer ready.\\nUse this for focused docs work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nDocs: http://127.0.0.1:8012'",
"features": {
"ghcr.io/cirolosapio/devcontainers-features/alpine-bash:0": {},
"ghcr.io/devcontainers/features/git:1": {}
Expand Down
14 changes: 0 additions & 14 deletions .devcontainer/frontend-app/devcontainer.json

This file was deleted.

13 changes: 0 additions & 13 deletions .devcontainer/frontend-web/devcontainer.json

This file was deleted.

13 changes: 13 additions & 0 deletions .devcontainer/www/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "relab-www",
"dockerComposeFile": ["../../compose.yaml", "../../compose.dev.yaml"],
"service": "www",
"runServices": ["www"],
"workspaceFolder": "/opt/relab/www",
"mounts": ["source=${localWorkspaceFolder},target=/opt/relab,type=bind,consistency=cached"],
"overrideCommand": true,
"postAttachCommand": "echo 'Relab web devcontainer ready.\\nUse this for focused web work; the root full-stack container is the default onboarding path.\\nRun just install if needed, then just dev or just check.\\nWeb: http://127.0.0.1:8013'",
"features": {
"ghcr.io/devcontainers/features/git:1": {}
}
}
54 changes: 54 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Version control
.git/
.gitignore

# Local environments and secrets
.env
.env.*
!.env.example
secrets/
backups/

# Python environments and caches
.venv/
**/.venv/
__pycache__/
**/__pycache__/
.ruff_cache/
.pytest_cache/
.mypy_cache/
.ty/

# Node dependencies and package-manager stores
node_modules/
**/node_modules/
.pnpm-store/

# Build outputs and test reports
dist/
**/dist/
coverage/
**/coverage/
playwright-report/
**/playwright-report/
test-results/
**/test-results/
.astro/
**/.astro/
.expo/
**/.expo/
web-build/
**/web-build/
reports/
**/reports/

# Editor and OS files
.vscode/
.idea/
.DS_Store

# Debug logs
npm-debug.*
yarn-debug.*
yarn-error.*
pnpm-debug.*
100 changes: 55 additions & 45 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,49 +1,59 @@
# Root .env — committed template for host-local secrets.
# Copy to `.env` on each deploy host (prod, staging, dev laptop) and fill in
# values. This file is auto-loaded by `docker compose` for `${VAR}`
# interpolation.
# Root .env.example - deploy operator checklist.
# Copy to `.env` on each deploy host and fill every required value.
#
# Non-secret per-environment config (APP_ENV, URLs, worker counts, …) lives
# in the committed `.env.prod.compose` / `.env.staging.compose` files at repo
# root — do not duplicate them here. The justfile `prod_compose` /
# `staging_compose` recipes pick the right one per environment.

COMPOSE_BAKE=true

# --- Cloudflare tunnel -----------------------------------------------
TUNNEL_TOKEN=your_token # 🔀 prod or staging token depending on this host

# --- Central monitoring stack (optional) ----------------------------
# All three vars below are OPTIONAL. Setting an endpoint enables the
# corresponding exporter; leaving it unset disables it. There is no separate
# on/off flag — the endpoint IS the switch.
#
# Auth pattern (when the central ingress is public-but-protected, e.g. behind a
# Cloudflare WAF rule requiring Authorization: Basic …):
# printf '%s:%s' relab "$SECRET" | base64 # → <base64>
# Loki driver has no custom-header config → auth goes in the URL.
# OTEL SDK reads OTEL_EXPORTER_OTLP_HEADERS → pass it there (URL-encode the space).
# Variable types:
# - Non-secret: safe to commit or place in `.env` when host-local review is easier.
# - Secret: never commit real values. Application/runtime secrets normally live
# in `secrets/<env>/`; only host/Compose helper secrets that must be
# interpolated by Compose are shown here.
#
# One-time, per host, before enabling Loki shipping:
# docker plugin install grafana/loki-docker-driver:latest \
# --alias loki --grant-all-permissions

# Logs → Loki push endpoint (auth embedded in URL)
# LOKI_URL=https://relab:<secret>@logs.cml-relab.org/loki/api/v1/push

# Traces/metrics → OTLP HTTP collector (+ matching auth header)
# OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp.cml-relab.org
# Committed prod/staging public environment identity lives in `deploy/env/*.compose.env`:
# ENVIRONMENT, API_PUBLIC_URL, APP_PUBLIC_URL, SITE_PUBLIC_URL, DOCS_PUBLIC_URL,
# and FEATURED_PRODUCT_ID.

# --- Required host-local deploy inputs --------------------------------

# Type: secret | Consumer: Cloudflare tunnel | Purpose: authenticates this host's tunnel.
CLOUDFLARE_TUNNEL_TOKEN=replace-me

# Type: non-secret | Consumer: backend auth | Purpose: OAuth public client IDs.
GOOGLE_OAUTH_CLIENT_ID=replace-me
GITHUB_OAUTH_CLIENT_ID=replace-me

# Type: non-secret | Consumer: backend email | Purpose: outbound email identity.
# Use `smtp` for SMTP relays, or `microsoft_graph` for Microsoft 365 Graph mail.
# Compose requires the shared identity fields below. Backend startup validation
# enforces the provider-specific fields and matching secret files.
EMAIL_PROVIDER=smtp
EMAIL_FROM="Relab <relab@example.org>"
EMAIL_REPLY_TO=relab@example.org

# Type: non-secret | Consumer: backend email | Purpose: required when EMAIL_PROVIDER=smtp.
SMTP_HOST=smtp.example.org
SMTP_USERNAME=relab@example.org
# Secret file required for SMTP: secrets/<env>/smtp_password

# Type: non-secret | Consumer: backend email | Purpose: required when EMAIL_PROVIDER=microsoft_graph.
# MICROSOFT_GRAPH_TENANT_ID=replace-me
# MICROSOFT_GRAPH_CLIENT_ID=replace-me
# MICROSOFT_GRAPH_SENDER_USER=relab@example.org
# Secret file required for Microsoft Graph: secrets/<env>/microsoft_graph_client_secret

# Type: non-secret | Consumer: backend bootstrap | Purpose: initial superuser identity.
BOOTSTRAP_SUPERUSER_EMAIL=admin@example.org

# Application/runtime secrets go in `secrets/<env>/`, not in this file.
# Create missing secret files with:
# just deploy-secrets-template prod
# just deploy-secrets-template staging

# --- Optional host-local deploy inputs --------------------------------

# Type: secret URL/header | Consumer: telemetry | Purpose: optional central monitoring.
# See deployment docs before enabling Loki/OTLP shipping.
# LOKI_PUSH_URL=https://relab:<secret>@<loki-push-host>/loki/api/v1/push
# OTEL_EXPORTER_OTLP_ENDPOINT=https://otel.cml-relab.org
# OTEL_EXPORTER_OTLP_HEADERS=Authorization=Basic%20<base64>

# --- Backup destinations ---------------------------------------------
BACKUP_DIR=./backups

# Remote rsync backup config (for use of backend/scripts/backup/rsync_backup.sh script)
BACKUP_RSYNC_REMOTE_HOST=user@host # 🔀
BACKUP_RSYNC_REMOTE_PATH=/path/to/remote/backup # 🔀

# Remote rclone backup config (for use of backend/scripts/backup/rclone_backup.sh script)
BACKUP_RCLONE_REMOTE=myremote:/path/to/remote/backup # 🔀
BACKUP_RCLONE_MULTI_THREAD_STREAMS=16
BACKUP_RCLONE_TIMEOUT=5m
BACKUP_RCLONE_USE_COOKIES=false
# Type: non-secret | Consumer: backup | Purpose: local restic repository path.
BACKUP_HOST_DIR=./backups
11 changes: 0 additions & 11 deletions .env.prod.compose

This file was deleted.

Loading