No description
- TypeScript 96.6%
- CSS 1.7%
- Shell 1%
- Dockerfile 0.4%
- JavaScript 0.3%
* feat(jdm): every public URL ends in a slash; the admin moves to /administration Production WordPress publishes one URL form, with a trailing slash, and 301s everything else onto it; the cutover must re-point no inbound link. #57 did that for articles and the archives followed by hand. This makes it the site's rule: a `trailingSlash` middleware on the public layouts (`_main`, and a new pathless `petitions.public` around the petition pages and the event page) 301s a slash-less GET/HEAD onto the slashed path, query kept, before any loader runs. Resource routes sit under no such layout and are never redirected. React Router 8's trailing-slash-aware data requests are the default, so nothing is enabled — but the middleware sees a data request's URL raw (`/x/_.data`), contrary to the upgrade guide, and strips the suffix itself; a file-shaped last segment is never slashed. `petition-url.ts` builds every petition link (sitemap, canonical, og:url, emails, cards, the menu default, the link resolvers) in the slashed form so nothing the app writes bounces. The admin moves from /petitions/admin to /administration — the sibling app's prefix — slash-less like OCF's: it was never on WordPress and nothing indexes it. One splat route 301s every old admin URL with its query; `administration` joins the reserved page slugs. Production nginx must route /administration to this app before this deploys. Fixes #81 * fix(jdm): restore the captured fixtures, test the admin redirect, finish the prefix sweep - The three WordPress capture fixtures are back byte for byte: Prettier run from the app directory does not read the root ignore file, and the reformat had lowercased the hex colour one assertion checks for. - tests/admin-redirect.test.ts pins the splat redirect's three shapes: the bare prefix, a deep path, a kept query. - The README, the seed script's comment, the admin shell's comment and the reimportable report's printed instruction say /administration; the doc's retired « still slash-less » sentence is gone. * fix(jdm): read the framework's normalized url in the trailing-slash middleware The middleware read `request.url`, the raw data request, and stripped the `.data` suffix by hand — which also copied the framework's own `_routes` param into the redirect. Every data function, middleware included, is handed a normalized `url` with the suffix and those params removed; the rule now reads that and nothing else. The petition page's privacy-policy link goes through `contentPagePath`, the last hand-written slash-less link. |
||
|---|---|---|
| .claude/rules | ||
| .github/workflows | ||
| .yarn/releases | ||
| apps | ||
| docs | ||
| packages | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| .mise.toml | ||
| .prettierignore | ||
| .prettierrc | ||
| .yarnrc.yml | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| package.json | ||
| README.md | ||
| yarn.lock | ||
Platform
Monorepo for two sites sharing one platform — a media library, a rich-text editor, admin UI, navigation menus, and one MariaDB:
- organisation-communiste — the OCF site: editorial pages, events and payments, media admin.
- jeunessedumonde — the JDM site: petitions, newsletters, and the articles being taken over from WordPress.
Shared code lives under packages/ (@ocf/db-migrate, @ocf/media, @ocf/editor,
@ocf/components, @ocf/menus), consumed as raw TS by both apps' builds.
Documentation
Start at docs/README.md — the index of the architecture write-ups
(one per shared package) and the feature docs, each mapped to its code entry points. The
CLAUDE.md files carry operating instructions; each app's README.md covers its own
setup in detail.
Prerequisites
- Mise — manages the Node version (
mise trust && mise install) - Docker — runs the shared infra (MariaDB, Redis, Mailpit, MinIO)
Setup
mise trust && mise install # Node (Yarn 4 rides on it via Corepack)
corepack enable
yarn install
docker compose up -d # shared infra for BOTH apps
yarn db:migrate # both apps' migrations, one coordinated pass
yarn db:seed # interactive: first admin account (works on both apps)
Each app needs its own .env — see the app READMEs for the variables.
Run
yarn jdm # jeunessedumonde → http://localhost:5173
yarn ocf # organisation-communiste → http://localhost:5183
Checks
yarn format:check # Prettier, whole repo (yarn format to fix)
yarn docs:check # every internal doc link/anchor resolves
yarn workspace <app> typecheck # per app: jeunessedumonde / organisation-communiste
yarn workspace <app> test # integration/unit suite
yarn workspace <app> test:e2e # Playwright journeys
CI runs all of these plus per-package typechecks/tests, Docker-manifest and
production-install guards (.github/workflows/).