Repository navigation
Conversation
This was referenced Jul 18, 2026
Preview: https://restarters-pr-898.fly.dev✅ Ready - restore and migrations succeeded.
|
fetchEvents and fetchGroups were near-identical (cached-fetch with loading/error/loaded bookkeeping, differing only in the /moderate endpoint). Extract a module-level loadSection(store, key, force, request) helper; the two public actions become thin wrappers. Kept it async with try/catch (not a .then/.catch chain) so a synchronous throw from request() - e.g. a missing $api in a test - is still caught, matching the original behaviour. Moderation + party/group-map/networks specs green; full suite 120 files / 930. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPQW8msJ8eya5XYsqk9B2S
…n set The "Other groups nearby" tab hardcoded hasLocation = true, so it never showed the legacy "You do not currently have a town/city set..." prompt - it always rendered the plain "nothing nearby" copy even for a user with no location. Wire hasLocation to the dashboard's has_location flag (the same source the dashboard and /party pages use; the nearby endpoint itself carries no such flag), fetching the dashboard on mount. Defaults true so the prompt never flashes while loading. + a spec for the no-location branch. group/nearby specs 7/7. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPQW8msJ8eya5XYsqk9B2S
The plain-layout header used justify-content-between; on mobile the impact-stats bar is hidden (d-none d-md-flex), leaving the logo alone and left-aligned. Legacy centred it on the register/landing mobile header. Use justify-content-center on mobile, justify-content-md-between on desktop. LogoStatsHeader spec 4/4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XPQW8msJ8eya5XYsqk9B2S
The API already accepts the postcode from hosts, limited to 32 characters. The form still made the field read-only unless the user could moderate, and did not cap its length. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Vite only bundles the moment locales that are imported, so moment.locale('fr')
silently stayed English and every date formatted with moment was English for
every user. Import the French locale and keep moment's locale in step with the
active locale, including when the user switches language. fr-BE falls back to
fr.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Picks up develop's new groups.distance key and the networks keys removed with the network page's count sentence. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…uses Develop dropped the key with the Blade follow buttons it replaced with the map. The Nuxt GroupJoinButton still shows the short Unfollow label on small screens. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… nuxt-client The groups table and network page are Nuxt components on this branch and already render every row, so the develop-side Vue edits are dropped with the deleted files; the new groups.show_all_groups lang key is kept. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ference-nuxt # Conflicts: # app/Http/Controllers/ExportController.php # mysql/my.cnf Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
| RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ | ||
| # Install Node 22 (Nuxt 4 / nuxi require Node >=22; matches client/Dockerfile | ||
| # node:22 and CI cimg/node:22.16. Vite 4 root build is Node-22-compatible too.) | ||
| RUN curl -fsSL --proto '=https' --tlsv1.2 https://deb.nodesource.com/setup_22.x | bash - \ |
| # Node 22 (runtime only) — runs the Nuxt Nitro server that serves the SPA origin | ||
| # (client/.output, started by supervisord). The .output targets Node >=22, same | ||
| # as the builder. This image only needs the node binary to run it. | ||
| RUN curl -fsSL --proto '=https' --tlsv1.2 https://deb.nodesource.com/setup_22.x | bash - \ |
| // Run: task parity:capture | ||
| const config = { | ||
| testDir: 'client/parity', | ||
| outputDir: '/tmp/test-results/parity-output', |
| # in here. Drop client/node_modules afterwards — .output is self-contained, and | ||
| # this keeps the final-stage `COPY /build` from dragging the dev install in. | ||
| WORKDIR /build/client | ||
| RUN npm ci --legacy-peer-deps |
| # leaks in. Install when the volume is empty or the lockfile changed. | ||
| if [ ! -f node_modules/.package-lock.json ] || ! cmp -s package-lock.json node_modules/.package-lock.json; then | ||
| echo "Installing client dependencies..." | ||
| npm ci |
| # Nuxt client container. Dev mode (NUXT_DEV_MODE=true, the docker-compose | ||
| # default) runs the HMR dev server against the bind-mounted source; otherwise | ||
| # it serves a production build — which is what CI's Playwright job tests. | ||
| FROM node:22-bookworm-slim |
When migrate fails, preview-startup.sh now writes the migration that was running, the exception class and the SQLSTATE and driver code into the public /_preview_status detail. The exception message is left out because it can quote restored production values. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nuxt-client The Vuex stores are deleted on this branch, and the Nuxt stores do not use the var loop keys the change fixes, so there is nothing to port. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ails Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Backend changes come across: the repair data export service and command, the stricter events-held count (kept alongside this branch's events_held), the device search filters, the networks.reporting_url migration and lang keys. The Vue components, Blade views and NetworkController that #926 edited are deleted on this branch; porting the reporting links, group stats layouts and Fixometer changes to the Nuxt client is not part of this merge. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A blank SENTRY_LARAVEL_DSN made Sentry throw InvalidOptionsException while reporting any exception, which hid the original error behind it. An empty value now disables reporting instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…without a SQL error Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A blank or whitespace SENTRY_LARAVEL_DSN secret is not a valid DSN, and Sentry threw InvalidOptionsException from artisan boot, so migrate failed on the restored preview database. Anything that is not an http(s) URL now means no DSN. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
develop removed years_volunteered and device_breakdown and the merge took its no_groups_mine, which links to a page that no longer exists here. The keys are restored with this branch's values and the client translations regenerated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ference-nuxt # Conflicts: # app/Http/Controllers/ExportController.php # client/i18n/locales/en.json # client/i18n/locales/fr-BE.json # client/i18n/locales/fr.json # lang/en/devices.php # lang/fr-BE/devices.php # lang/fr/devices.php Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Group page: ?stats_layout= switches between compact (default), after and
split, the compact layout leaves out the not-counting note, and the cluster
breakdown is gone as on develop. Group members and hosts get a reports link in
the actions menu and under the stats, from a reporting_url on the group
resource that is null for everyone else.
Network page: reports link in the actions menu and under the impact figures;
administrators set the dashboard address on the edit page through a new
PATCH /api/v2/networks/{id}, which coordinators cannot use.
Fixometer: events held and items seen tiles, the fixed-items labels, a
further-reports link, and a download button for everyone that serves the
overnight file when it exists, from download_url and reporting_url on
homepage_data.
The reporting-link, repair-data-file and export tests now go through the API,
the export test reads the response's own temp file, and lang keys nothing uses
on this branch are removed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…filter key test and a lint error Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…eption handling in the 422 and 401 tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ference-nuxt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nuxt feat: optional reference field on devices
…board rejection, drop Math.random from optimistic ids Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Summary
client/) that talks to Laravel exclusively via/api/v2./api/v2plus a small pinned web surface (SSO bridge, emailed/shared deep-link redirectors, anonymous exports + calendar feeds, embeddable stats widgets, admin preview-deploy) and a catch-all that 302-redirects any other browser navigation to the SPA.tests/Feature/ApiOnlyRouteSurfaceTestpins that surface.laravel/ui, the 5 auth controllers, ~200 Blade views,resources/js/resources/sass, Jest, thebuild-legacy-frontendCI job, and the legacy global jQuery (resources/global/js/app.js).What's included
Nuxt 4 SPA: Vue 3, Pinia, bootstrap-vue-next (Bootstrap 5),
@nuxtjs/i18n, Vitest, Playwright e2e. All pages ported: dashboard, groups (+ map/nearby/all/create/edit), events (+ create/view/devices/attendees), fixometer, profile (view + edit tabs), admin reference-data, user/all, networks, notifications, auth.Auth: Sanctum bearer + dual guard
auth:sanctum,api; an SSO bridge (/auth/bridge) minting a web session for Discourse SSO + MediaWiki silent login.Infra: docker-compose split into Nuxt + API containers; CI four-job topology (
build,build-client,e2e-client); client translations exported fromlang/*.php. CI falls back to the stub geocoder when no geocoding key is available (forked PRs), and the dev deploy job fails unless the app is actually serving.Groups map and list match develop: filtering the list (name, and tags for people who can manage them) moves the pins and reframes the map once typing stops; the map opens on the user's own area (nearest groups, or the groups in their country when they have only set a country) and the place search is preloaded with it; the list is ordered by distance and badges archived groups.
Network page: the Groups section is a map and filterable list of the network's groups; the groups tally counts only non-archived groups; hosts can edit their group's postcode (max 32 characters).
Dates formatted with moment follow the active locale (fr, and fr-BE via fr), including after a language switch.
Open Repair Data Standard export at
GET /api/v2/repairs(Administrator only; 503 untilORDS_ID_PREFIXandORDS_DATA_PROVIDERare set).Design parity with the live site (G6) — reviewed page-by-page against production and matched:
.panel/.panel__orangecards with the offset drop-shadow (ported the legacy_panels.scssinto the global layer — no component overrides)..content-divider; brand cards global, only page-specific layout scoped./images/*set populated.API security review (verified against the pre-migration controllers) — fixed a critical device IDOR, an open redirect in the SSO bridge, an event-visibility regression (unmoderated-group events were public), and a password-reset token replay; each with a regression test. See
docs/nuxt-migration/findings/security-review-api.md.Output escaping and credential rotation: the group and event audit-log endpoints escape the user name, request URL and old/new values before substituting them into the HTML log lines; the group page's unfollow banner escapes the group name; rich-text descriptions are sanitised on write (
stevebauman/purify); a password reset clears the recovery code and revokes the user's tokens, and a password change revokes the others instead of minting a recovery code; CSV exports neutralise spreadsheet-formula cells.Code Quality Review
ApiOnlyRouteSurfaceTest) and per-endpoint OpenAPI response validation guard against surface/shape drift.role/api_tokenexcluded from$fillable; Eloquent bindings — no raw SQL).wiki.js) and the embeddable widget pages' CDN libs — both outside the Vue/Nuxt app.Test Plan
buildphpunit,build-clientvitest + lint + build,e2e-clientPlaywright) run on the branch head. Locally: client vitest 1658 tests in 161 files, lint, and the Nuxt build pass.APIv2PublicProfileTest,APIv2DeviceUpdateAuthTest,APIv2EventVisibilityTest,SsoBridgeTest,AuthEndpointsTest,PasswordResetHardeningTest,StoredXssHardeningTest,AuthorizationHardeningTest,DashboardAddData.spec, e2e for dashboard/device/event flows).Future Improvements
docs/nuxt-migration/findings/): the SSO bridge is irreducibly a web route; the redirectors + catch-all could move to nginx; admin preview-deploy should move into the SPA + an/api/v2endpoint (it currently can't authenticate the SPA user, which is a session-vs-token mismatch). The anonymous export/calendar feeds and embeddable stats widgets are kept for external consumers/partners.security-review-api.md(repair-directory read gate, dead v1/api/groups/dump, dead draft-image copy path, tus filename-collision + disk-fill sweep, throttle gaps). The public group directory + shareable-link exposure were reviewed and deliberately left as-is.🤖 Generated with Claude Code