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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .easignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Trimmed from the EAS build upload. Never exclude a workspace package: EAS runs
# `pnpm install --frozen-lockfile` at the root, and a missing package makes the
# lockfile diverge (ERR_PNPM_OUTDATED_LOCKFILE).
docs/
docker/
.github/
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ labels: bug

**Environment**

- App: web / mobile / admin / api
- App: mobile / api
- Version or commit:
60 changes: 50 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,54 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
DATABASE_URL: postgresql://wantere:wantere@localhost:5432/wantere?schema=public
REDIS_URL: redis://localhost:6379
JWT_SECRET: ci-secret-value-that-is-long-enough-32
JWT_REFRESH_SECRET: ci-refresh-secret-long-enough-32-chars

jobs:
quality:
mobile:
name: Mobile
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
cache: pnpm

- run: pnpm install --frozen-lockfile

# `pnpm --filter` runs each package script directly, which bypasses the
# `dependsOn: ["^build"]` of turbo.json: the shared packages compile to
# dist/ and nothing would build them. Same list as the EAS hook.
- name: Build the shared packages
run: >-
pnpm exec turbo run build
--filter=@p2p-local/config --filter=@p2p-local/design-tokens
--filter=@p2p-local/types --filter=@p2p-local/validation

- run: pnpm --filter @p2p-local/mobile... lint

- run: pnpm --filter @p2p-local/mobile... typecheck

- run: pnpm --filter @p2p-local/mobile test

# Informative: expo-doctor reaches the Expo registry and reports drift in
# transitive versions we do not control.
- name: Check the Expo project
run: pnpm --filter @p2p-local/mobile exec expo-doctor
continue-on-error: true

api:
name: API
runs-on: ubuntu-latest

env:
DATABASE_URL: postgresql://wantere:wantere@localhost:5432/wantere?schema=public
REDIS_URL: redis://localhost:6379
JWT_SECRET: ci-secret-value-that-is-long-enough-32
JWT_REFRESH_SECRET: ci-refresh-secret-long-enough-32-chars

services:
postgres:
image: postgis/postgis:17-3.5
Expand Down Expand Up @@ -57,7 +95,7 @@ jobs:
- run: pnpm install --frozen-lockfile

- name: Apply database migrations
run: pnpm --filter @wantere/api db:deploy
run: pnpm --filter @p2p-local/api db:deploy

- run: pnpm lint

Expand All @@ -66,6 +104,8 @@ jobs:
- run: pnpm test

- name: Run end-to-end tests
run: pnpm --filter @wantere/api test:e2e
run: pnpm --filter @p2p-local/api test:e2e

- run: pnpm build
# The mobile bundle is built by EAS, not here: `expo export` is slow and
# reaches the network for no verification CI does not already have.
- run: pnpm build --filter=!@p2p-local/mobile
45 changes: 45 additions & 0 deletions .github/workflows/eas-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: EAS build

# Manual only: a build consumes quota and takes 15 to 30 minutes, which makes it
# unusable on every pull request.
on:
workflow_dispatch:
inputs:
profile:
description: Profil EAS
type: choice
options: [preview, production]
default: preview
platform:
description: Plateforme
type: choice
options: [android, ios, all]
default: android

jobs:
build:
name: Build ${{ inputs.platform }} (${{ inputs.profile }})
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v5
with:
node-version-file: .nvmrc
cache: pnpm

# Requires an EXPO_TOKEN repository secret, created from an Expo access
# token that can build this project.
- uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- run: pnpm install --frozen-lockfile

- name: Trigger the build
working-directory: apps/mobile
run: eas build --platform ${{ inputs.platform }} --profile ${{ inputs.profile }} --non-interactive --no-wait
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ dist
build
coverage
.turbo
.next
out
.expo
*.tsbuildinfo
next-env.d.ts
expo-env.d.ts
apps/api/src/generated

Expand Down
1 change: 0 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pnpm-lock.yaml
node_modules
dist
.next
.expo
coverage
packages/api-client/src/generated
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"@wantere/prettier-config"
"@p2p-local/prettier-config"
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Our pledge

We want participation in Wantere to be a harassment-free experience for
We want participation in P2P Local to be a harassment-free experience for
everyone, regardless of age, body size, disability, ethnicity, gender identity
and expression, level of experience, nationality, personal appearance, race,
religion, or sexual identity and orientation.
Expand Down
49 changes: 37 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
## Setup

```bash
cp apps/api/.env.example apps/api/.env
cp apps/web/.env.example apps/web/.env
cp apps/admin/.env.example apps/admin/.env
cp apps/mobile/.env.example apps/mobile/.env

pnpm install
pnpm --filter @p2p-local/mobile dev
```

The V1 mobile application needs nothing else: no server, no environment
variable. To work on the API:

```bash
cp apps/api/.env.example apps/api/.env
pnpm docker:up
pnpm db:migrate && pnpm db:seed
pnpm dev
pnpm --filter @p2p-local/api dev
```

## Before opening a pull request
Expand All @@ -32,16 +35,36 @@ pnpm api:generate

## Conventions

- Conventional Commits: `feat(api): add offer negotiation`, `fix(web): ...`.
- Conventional Commits: `feat(mobile): add the district picker`, `fix(api): ...`.
- Code is organised by domain, not by technical layer. A new business concept
gets its own module under `apps/api/src/modules`.
- NestJS owns the business rules. The web and mobile applications consume the
API; they do not reimplement validation or authorization.
gets its own module under `apps/api/src/modules`, or its own folder under
`apps/mobile/features`.
- The V1 mobile app has no backend. Listings live on the device behind
`ListingRepository`; screens never touch AsyncStorage directly. Every read and
write goes through the repository interface, so a server implementation can
replace it without rewriting a screen.
- The API owns the business rules for anything it serves. Clients consume it;
they do not reimplement validation or authorization.
- Comments explain decisions, constraints or workarounds — not what the code
already says.
- Public API responses must never expose a member's exact location, phone
number or internal moderation state.

This rule covers the API. The mobile app does not display a phone number
either: it only builds a `wa.me` link at the moment of the tap. That the
author of a listing becomes reachable at all is a contradiction with the
promise made during framing, and it is an open team decision — see
[docs/design/README.md](docs/design/README.md).

## Mobile application

- Add an Expo dependency with `npx expo install <package>`, never with a version
written by hand: only `expo install` knows what the SDK is compatible with.
`npx expo install --check` reports drift, `--fix` corrects it.
- `npx expo-doctor` must pass before opening a pull request.
- Application icons are generated: edit `apps/mobile/assets/source/*.svg`, run
`pnpm --filter @p2p-local/mobile assets:build`, and commit the resulting PNGs.

## Database changes

Update `apps/api/prisma/schema.prisma`, then:
Expand All @@ -58,7 +81,9 @@ hand-written migration, since Prisma cannot express it.
- Unit tests live next to the code as `*.spec.ts`.
- End-to-end tests live in `apps/api/test` and run against a real Postgres and
Redis.
- On mobile, pure functions (formatting, WhatsApp links) and the storage
repository are tested. Screen rendering is not tested in V1.

Test what carries risk: authorization, money-adjacent rules, privacy of
locations, search behaviour. Tests asserting that a service is defined are not
useful.
locations and phone numbers, search behaviour. Tests asserting that a service is
defined are not useful.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2026 Wantere contributors
Copyright (c) 2026 P2P Local contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading
Loading