diff --git a/.project/concepts/data-layer/brief_2026-10-09_activitypods-first-backend.md b/.project/concepts/data-layer/brief_2026-10-09_activitypods-first-backend.md index 7c7a607..9695a23 100644 --- a/.project/concepts/data-layer/brief_2026-10-09_activitypods-first-backend.md +++ b/.project/concepts/data-layer/brief_2026-10-09_activitypods-first-backend.md @@ -37,7 +37,7 @@ Reading these at this stage is adoption-time reading, explicitly directed — th ## Open questions -- Participation topology — the one real divergence from the 2026-10-03 structure: welcometomyplace keeps the canonical list creator-side (an `apods:attendees` collection on the event, writes backend-mediated), where the two-rights-models structure makes each participation a participant-owned document. Both land on the same application state (a reference that may or may not resolve); the choice is who owns the write path. To arbitrate before implementation. +- Participation topology — the one real divergence from the 2026-10-03 structure: welcometomyplace keeps the canonical list creator-side (an `apods:attendees` collection on the event, writes backend-mediated), where the two-rights-models structure makes each participation a participant-owned document. Both land on the same application state (a reference that may or may not resolve); the choice is who owns the write path. **Arbitration route decided 2026-10-09: the implementation plan evaluates both against the concrete screens (count, withdrawal, discovery, reference non-resolution) and submits an argued recommendation before anything is frozen.** - `as:Join` has a shape but no shape tree: if participations must be addressable as resources in access needs, adding `shapetrees/as/Join.ttl` for an already-existing AS type is the minimal move — or the collection pattern makes it unnecessary. - The backend's deployment shape (service alongside the app? a platform app?). - Whether the four pointed-to provider contributions (from the hand-off) are still the right set once the backend exists — some may move from "contribution to the providers" to "our backend's job". diff --git a/.project/concepts/data-layer/cookbook_local-activitypods-platform.md b/.project/concepts/data-layer/cookbook_local-activitypods-platform.md new file mode 100644 index 0000000..3ad8490 --- /dev/null +++ b/.project/concepts/data-layer/cookbook_local-activitypods-platform.md @@ -0,0 +1,37 @@ +--- +type: cookbook +summary: Bring up a local ActivityPods pod provider for Festipod development — ports, the reproducible signup → login → create-as/Event flow, the fresh-pod container behaviour, teardown +--- + +# Cookbook — Local ActivityPods platform + +Platform checkout: `/home/sylvain/projects/activitypods/activitypods` (never modify it; verified pristine 2026-10-09). Everything runs from `pod-provider/`. + +## Ports + +fuseki 3030 (admin/admin), mailcatcher 1080, redis 6379, backend 3000, frontend 5000, arena 4567, tripleadmin 3033. + +## Bring up + +1. Infra: `cd pod-provider && docker compose up -d`. If host port 6379 is already taken, add an override file publishing redis on another port (6390 was used) and pass `SEMAPPS_QUEUE_SERVICE_URL=redis://localhost:6390/1` and `SEMAPPS_REDIS_OIDC_PROVIDER_URL=redis://localhost:6390/2` when starting the backend — dotenv-flow does not override the process environment. +2. Install once: `cd backend && COREPACK_ENABLE_AUTO_PIN=0 corepack yarn install --frozen-lockfile`, same in `frontend/`. Keep `COREPACK_ENABLE_AUTO_PIN=0`: corepack auto-pin rewrites `packageManager` in package.json. Note: the pod-provider README says `yarn start` for the frontend; only the `dev` script exists — use `BROWSER=none corepack yarn dev`. +3. Backend: `cd backend && corepack yarn start`. Wait for "ServiceBroker with ... service(s) started successfully" (~11 s). +4. Frontend: `cd frontend && BROWSER=none corepack yarn dev`. Verify: `GET http://localhost:5000/` → 200 and `GET http://localhost:3000/.well-known/config.js` → 200. + +## Account and resource flow (all VERIFIED 2026-10-09) + +- Signup: `POST http://localhost:3000/auth/signup`, `Content-Type: application/json` (NOT JSON-LD), body `{"username":"alice","email":"alice@test.com","password":"Test1test","name":"Alice","schema:knowsLanguage":"en"}` → 200 `{"token":"...","webId":"http://localhost:3000/alice","newUser":true}` (~10 s, pod-creation hooks). +- Login: `POST http://localhost:3000/auth/login`, same content type, `{"username":"alice","password":"Test1test"}` → 200 with token; wrong password → 401. +- Read the actor: `GET http://localhost:3000/alice`, `Authorization: Bearer `, `Accept: application/ld+json` → 200; gives `pim:storage` (`http://localhost:3000/alice/data`). +- Create an event: `POST `, Bearer + `Content-Type: application/ld+json`, body `{"@context":"https://activitypods.org/context.json","type":"Event","name":"...","startTime":"...","endTime":"..."}` → 201 + `Location`. +- Re-read `Location` with Bearer → 200 full JSON-LD; without token → 403 (WAC: private by default). + +## Fresh-pod behaviour + +On a fresh pod, an `as:Event` POST lands at the pod root (`/alice/data/`): typed containers such as `/alice/data/as/event` exist only after a user installs an app whose access needs declare that shape tree. Do not expect typed containers before app registration. + +## Teardown + +`pkill -f moleculer-runner; pkill -f react-scripts`, then `docker compose down` in `pod-provider/`. Data persists in `pod-provider/data/` (gitignored); delete that directory to fully reset. + +Current stack test account: `alice` / `Test1test` on localhost:3000.